# HNOI2018

## 寻宝游戏（位运算、基数排序）

#include<iostream>
#include<cstdio>
#include<cstring>
#include<iomanip>
//This code is written by Itst
using namespace std;

const int MOD = 1e9 + 7;
int srt[5007] , val[5007] , tmp[5007] , pot[3];
int N , M , Q;
char s[5007];

int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
scanf("%d %d %d" , &N , &M , &Q);
for(int i = 1 ; i <= M ; ++i)
srt[i] = i;
int times = 1;
for(int i = 1 ; i <= N ; ++i){
pot[0] = pot[1] = 0;
scanf("%s" , s + 1);
for(int j = 1 ; j <= M ; ++j){
++pot[s[j] - 47];
if(s[j] - 48)
val[j] = (val[j] + times) % MOD;
}
for(int j = 1 ; j <= M ; ++j)
tmp[++pot[s[srt[j]] - 48]] = srt[j];
memcpy(srt , tmp , sizeof(tmp));
times = times * 2 % MOD;
}
srt[M + 1] = M + 1;
val[M + 1] = times;
while(Q--){
scanf("%s" , s + 1);
int L = 0 , R = M + 1;
for(int i = 1 ; i <= M ; ++i)
if(s[srt[i]] == '1'){
R = i;
break;
}
for(int i = M ; i ; --i)
if(s[srt[i]] == '0'){
L = i;
break;
}
if(L > R)
puts("0");
else
printf("%d\n" , (val[srt[R]] - val[srt[L]] + MOD) % MOD);
}
return 0;
}


## 转盘（线段树、单调栈）

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cctype>
#include<algorithm>
//This code is written by Itst
using namespace std;

int a = 0;
char c = getchar();
while(!isdigit(c))
c = getchar();
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return a;
}

const int MAXN = 1e5 + 7;
struct node{
int rgL , rgR , maxN , ans;
}Tree[MAXN << 3];
int val[MAXN << 1] , N , M , P;

#define lch (x << 1)
#define rch (x << 1 | 1)
#define mid ((l + r) >> 1)
#define PII pair < int , int >

int find(int x , int dir){
if(Tree[x].rgL == Tree[x].rgR)
return Tree[x].rgL + dir + 1;
if(Tree[rch].maxN > dir)
return min(Tree[x].ans , find(rch , dir));
return find(lch , dir);
}

inline void pushup(int x){
Tree[x].maxN = max(Tree[rch].maxN , Tree[lch].maxN);
Tree[x].ans = find(lch , Tree[rch].maxN);
}

void init(int x , int l , int r){
Tree[x].rgL = l;
Tree[x].rgR = r;
Tree[x].ans = 0x7fffffff;
if(l == r)
Tree[x].maxN = val[l] - l;
else{
init(lch , l , mid);
init(rch , mid + 1 , r);
pushup(x);
}
}

void modify(int x , int l , int r , int tar){
if(l == r){
Tree[x].maxN = val[tar] - tar;
return;
}
if(mid >= tar)
modify(lch , l , mid , tar);
else
modify(rch , mid + 1 , r , tar);
pushup(x);
}

int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
for(int i = 1 ; i <= N ; ++i)
val[i] = val[i + N] = read();
init(1 , 1 , N << 1);
int lastans = Tree[1].ans + N - 1;
cout << lastans << '\n';
for(int i = 1 ; i <= M ; ++i){
val[x] = val[x + N] = y;
modify(1 , 1 , N << 1 , x);
modify(1 , 1 , N << 1 , x + N);
cout << (lastans = Tree[1].ans + N - 1) << '\n';
}
return 0;
}


## 毒瘤（虚树）

#include<iostream>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<vector>
#include<cmath>
//This code is written by Itst
using namespace std;

int a = 0;
char c = getchar();
while(!isdigit(c))
c = getchar();
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return a;
}

const int MAXN = 1e5 + 13 , MOD = 998244353;
struct Edge{
int end , upEd;
}Ed[MAXN << 1];
int head[MAXN] , DP[MAXN][2] , dep[MAXN] , dfn[MAXN] , jmp[MAXN][19];
int N , M , cntEd = 1 , cnt , ts , mr[21];

inline void addEd(int a , int b){
Ed[++cntEd].end = b;
}

#define go(a , b , c) (a = 1ll * a * (b + c) % MOD)
void dfs(int x , int p){
dep[x] = dep[p] + 1;
dfn[x] = ++ts;
jmp[x][0] = p;
for(int i = 1 ; i <= 16 ; ++i)
jmp[x][i] = jmp[jmp[x][i - 1]][i - 1];
DP[x][0] = DP[x][1] = 1;
for(int i = head[x] ; i ; i = Ed[i].upEd)
if(Ed[i].end != p)
if(!dep[Ed[i].end]){
dfs(Ed[i].end , x);
go(DP[x][0] , DP[Ed[i].end][0] , DP[Ed[i].end][1]);
DP[x][1] = 1ll * DP[x][1] * DP[Ed[i].end][0] % MOD;
}
else
if(dep[Ed[i].end] > dep[x])
mr[++cnt] = i;
}

bool cmp(int a , int b) {return dfn[a] < dfn[b];}

inline int LCA(int x , int y){
if(dep[x] < dep[y])
x ^= y ^= x ^= y;
for(int i = 16 ; i >= 0 ; --i)
if(dep[x] - (1 << i) >= dep[y])
x = jmp[x][i];
if(x == y)
return x;
for(int i = 16 ; i >= 0 ; --i)
if(jmp[x][i] != jmp[y][i]){
x = jmp[x][i];
y = jmp[y][i];
}
return jmp[x][0];
}

#define pb push_back
#define add(a , b) (a + b >= MOD ? a + b - MOD : a + b)
vector < int > ch[MAXN] , nd;
int dp[MAXN][2] , xs[MAXN][2][2] , st[101] , top , cntN;
bool mrk[MAXN];

void calc(int x){
xs[x][0][0] = xs[x][1][1] = 1;
for(int i = head[x] ; i ; i = Ed[i].upEd)
if(!mrk[Ed[i].end] && jmp[Ed[i].end][0] == x){
go(xs[x][0][0] , DP[Ed[i].end][1] , DP[Ed[i].end][0]);
xs[x][1][1] = 1ll * xs[x][1][1] * DP[Ed[i].end][0] % MOD;
}
int p = x;
while(!mrk[jmp[p][0]] && jmp[p][0]){
mrk[p = jmp[p][0]] = 1;
int P = xs[x][0][0] , Q = xs[x][0][1];
xs[x][1][0] = P;
xs[x][1][1] = Q;
for(int i = head[p] ; i ; i = Ed[i].upEd)
if(jmp[Ed[i].end][0] == p && !mrk[Ed[i].end]){
go(xs[x][0][0] , DP[Ed[i].end][1] , DP[Ed[i].end][0]);
go(xs[x][0][1] , DP[Ed[i].end][1] , DP[Ed[i].end][0]);
xs[x][1][0] = 1ll * xs[x][1][0] * DP[Ed[i].end][0] % MOD;
xs[x][1][1] = 1ll * xs[x][1][1] * DP[Ed[i].end][0] % MOD;
}
}
}

void DFS(int x){
mrk[x] = 1;
for(int i = 0 ; i < ch[x].size() ; ++i)
DFS(ch[x][i]);
calc(x);
}

void init(){
nd.pb(1);
for(int i = 1 ; i <= cnt ; ++i){
nd.pb(Ed[mr[i]].end);
nd.pb(Ed[mr[i] ^ 1].end);
}
sort(nd.begin() , nd.end() , cmp);
cntN = unique(nd.begin() , nd.end()) - nd.begin();
for(int i = 0 ; i < cntN ; ++i){
if(top){
int t = LCA(st[top] , nd[i]);
while(top - 1 && dep[t] <= dep[st[top - 1]]){
ch[st[top - 1]].pb(st[top]);
--top;
}
if(dep[t] < dep[st[top]]){
ch[t].pb(st[top]);
st[top] = t;
}
}
st[++top] = nd[i];
}
while(top - 1){
ch[st[top - 1]].pb(st[top]);
--top;
}
DFS(1);
}

int sum , zt[MAXN];
void getans(int x){
dp[x][0] = zt[x] == 0 || zt[x] == 1;
dp[x][1] = zt[x] == 0 || zt[x] == 2;
for(int i = 0 ; i < ch[x].size() ; ++i){
getans(ch[x][i]);
go(dp[x][0] , dp[ch[x][i]][0] , dp[ch[x][i]][1]);
dp[x][1] = 1ll * dp[x][1] * dp[ch[x][i]][0] % MOD;
dp[ch[x][i]][0] = dp[ch[x][i]][1] = 0;
}
int p = dp[x][0] , q = dp[x][1];
dp[x][0] = (1ll * xs[x][0][0] * p + 1ll * xs[x][0][1] * q) % MOD;
dp[x][1] = (1ll * xs[x][1][0] * p + 1ll * xs[x][1][1] * q) % MOD;
}

void Dfs(int x){
if(x > cnt){
getans(1);
sum = (0ll + sum + dp[1][0] + dp[1][1]) % MOD;
dp[1][0] = dp[1][1] = 0;
return;
}
int l = Ed[mr[x]].end , r = Ed[mr[x] ^ 1].end , p = zt[l] , q = zt[r];
if((p == 0 || p == 1) && (q == 0 || q == 2)){
zt[l] = 1; zt[r] = 2;
Dfs(x + 1);
zt[l] = p; zt[r] = q;
}
if(q == 0 || q == 1){
zt[r] = 1;
Dfs(x + 1);
zt[r] = q;
}
}

int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
for(int i = 1 ; i <= M ; ++i){
}
dfs(1 , 0);
init();
Dfs(1);
cout << sum;
return 0;
}


## 游戏（拓扑排序）

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<vector>
#include<cmath>
#include<cassert>
//This code is written by Itst
using namespace std;

int a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c) && c != EOF){
if(c == '-')
f = 1;
c = getchar();
}
if(c == EOF)
exit(0);
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return f ? -a : a;
}

const int MAXN = 1e6 + 7;
vector < int > door , ch[MAXN];
int lft[MAXN] , rht[MAXN] , L[MAXN] , R[MAXN] , in[MAXN];
int N , M;

inline void add(int x , int y){
++in[y];
ch[x].push_back(y);
}

queue < int > q , work;
void TopSort(){
for(int i = 1 ; i <= M ; ++i)
if(!in[i])
q.push(i);
while(!q.empty()){
int t = q.front();
q.pop();
work.push(t);
for(int i = 0 ; i < ch[t].size() ; ++i)
if(!--in[ch[t][i]])
q.push(ch[t][i]);
}
}

inline int find(int x){
return lower_bound(door.begin() , door.end() , x) - door.begin();
}

inline void calc(int x){
while(L[x] != 1 || door[R[x]] != N){
if(L[x] != 1 && rht[door[L[x] - 1] + 1] && rht[door[L[x] - 1] + 1] <= door[R[x]]){
L[x] = L[L[x] - 1];
continue;
}
if(door[R[x]] != N && lft[door[R[x]]] >= door[L[x] - 1] + 1){
R[x] = R[R[x] + 1];
continue;
}
break;
}
}

int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
for(int i = 1 ; i <= M ; ++i){
y <= x ? lft[x] = y : rht[x + 1] = y;
door.push_back(x);
}
++M;
door.push_back(0);
door.push_back(N);
sort(door.begin() , door.end());
for(int i = 1 ; i <= M ; ++i){
L[i] = R[i] = i;
if(rht[door[i - 1] + 1])
if(lft[door[i]])
}
TopSort();
while(!work.empty()){
calc(work.front());
work.pop();
}
while(Q--){
puts(door[L[l] - 1] + 1 <= r && door[R[l]] >= r ? "YES" : "NO");
}
return 0;
}


## 排列（贪心、并查集）

#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;

int a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c)){
if(c == '-')
f = 1;
c = getchar();
}
while(isdigit(c)){
a = (a << 3) + (a << 1) + (c ^ '0');
c = getchar();
}
return f ? -a : a;
}

const int MAXN = 5e5 + 10;
struct Edge{
int end , upEd;
}Ed[MAXN << 1];
int head[MAXN] , pre[MAXN << 1] , fa[MAXN << 1] , ch[MAXN << 1][2] , size[MAXN << 1] , cntEd , cntNode , N , t;
long long pri[MAXN << 1] , ans;
bool vis[MAXN] , mark[MAXN << 1];
struct cmp{
bool operator ()(int a , int b){
return pri[a] * size[b] > pri[b] * size[a];
}
};
priority_queue < int , vector < int > , cmp > q;

int find(int x){
return fa[x] == x ? x : (fa[x] = find(fa[x]));
}

inline void addEd(int a , int b){
Ed[++cntEd].end = b;
}

bool dfs(int x , int p){
pre[x] = p;
vis[x] = 1;
for(int i = head[x] ; i ; i = Ed[i].upEd)
if(Ed[i].end != p)
if(vis[Ed[i].end] || dfs(Ed[i].end , x))
return 1;
return 0;
}

void color(int x){
if(x <= N)
ans += t++ * pri[x];
else{
color(ch[x][0]);
color(ch[x][1]);
}
}

int main(){
#ifndef ONLINE_JUDGE
freopen("in" , "r" , stdin);
//freopen("out" , "w" , stdout);
#endif
size[0] = 1;
for(int i = 1 ; i <= N ; ++i){
fa[i] = i;
size[i] = 1;
}
for(int i = 1 ; i <= N ; ++i){
q.push(i);
}
for(int i = 0 ; i <= N ; ++i)
if(!vis[i])
if(dfs(i , -1)){
puts("-1");
return 0;
}
while(!q.empty()){
int t = q.top();
q.pop();
if(mark[t])
continue;
int f = find(pre[t]) , x = ++cntNode;
fa[f] = fa[t] = fa[x] = x;
size[x] = size[f] + size[t];
pri[x] = pri[f] + pri[t];
ch[x][0] = f;
ch[x][1] = t;
pre[x] = pre[f];
mark[t] = mark[f] = 1;
if(pre[x] != -1)
q.push(x);
}
color(cntNode);
cout << ans;
return 0;
}



## 道路（树形DP）

#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;

int a = 0;
bool f = 0;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = 1;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << 3) + (a << 1) + (c ^ '0');
c = getchar();
}
return f ? -a : a;
}

const int MAXN = 20010;
long long dp[1010][41][41] , num[MAXN][3];
int ch[MAXN][2] , headSt , N;

void dfs(int now){
if(now < 0){
now = -now;
for(int i = 0 ; i <= 40 ; ++i)
for(int j = 0 ; j <= 40 ; ++j)
dp[headSt][i][j] = (num[now][0] + i) * (num[now][1] + j) * num[now][2];
return;
}
dfs(ch[now][0]);
dfs(ch[now][1]);
for(int i = 0 ; i < 40 ; ++i)
for(int j = 0 ; j < 40 ; ++j)
}

int main(){
for(int i = 1 ; i < N ; i++){
}
for(int i = 1 ; i <= N ; i++){
}
dfs(1);
cout << dp[1][0][0];
return 0;
}


## HNOI2018做题笔记的更多相关文章

1. C语言程序设计做题笔记之C语言基础知识(下)

C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...

2. C语言程序设计做题笔记之C语言基础知识（上）

C语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行事.并且C是相当灵活的,用于执行计算机程序能完成的几乎 ...

3. SDOI2017 R1做题笔记

SDOI2017 R1做题笔记 梦想还是要有的,万一哪天就做完了呢? 也就是说现在还没做完. 哈哈哈我竟然做完了-2019.3.29 20:30

4. SDOI2014 R1做题笔记

SDOI2014 R1做题笔记 经过很久很久的时间,shzr又做完了SDOI2014一轮的题目. 但是我不想写做题笔记(

5. SDOI2016 R1做题笔记

SDOI2016 R1做题笔记 经过很久很久的时间,shzr终于做完了SDOI2016一轮的题目. 其实没想到竟然是2016年的题目先做完,因为14年的六个题很早就做了四个了,但是后两个有点开不动.. ...

6. LCT做题笔记

最近几天打算认真复习LCT,毕竟以前只会板子.正好也可以学点新的用法,这里就用来写做题笔记吧.这个分类比较混乱,主要看感觉,不一定对: 维护森林的LCT 就是最普通,最一般那种的LCT啦.这类题目往往 ...

7. java做题笔记

java做题笔记 1. 初始化过程是这样的: 1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化: 2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序 ...

8. SAM 做题笔记（各种技巧，持续更新，SA）

SAM 感性瞎扯. 这里是 SAM 做题笔记. 本来是在一篇随笔里面,然后 Latex 太多加载不过来就分成了两篇. 标 * 的是推荐一做的题目. trick 是我总结的技巧. I. P3804 [模 ...

9. PKUWC/SC 做题笔记

去年不知道干了些啥,什么省选/营题都没做. 现在赶应该还来得及(?) 「PKUWC2018」Minimax Done 2019.12.04 9:38:55 线段树合并船新玩法??? \(O(n^2)\ ...

## 随机推荐

1. java内省机制Introspector

访问JavaBean属性的两种方式 1)直接调用bean的setXXX或getXXX方法: 2)通过内省技术访问(java.beans包提供了内省的API),内省技术访问也提供了两种方式: a)通过P ...

2. 你不知道的JSON的高效率用法

1.JSON JSON是JavaScript Object Notation的缩写,是JavaScript标准的一个子集.官方Android API已经内置支持读写JSON数据.这种格式非常适合表示不 ...

3. 认识k_BackingField【转】

事情从Json的序列化和反序列化说起. 在C#2.0的项目中,以前经常使用Json.Net实现序列化和反序列化.后来从c#3.0中开始使用新增的DataContractJsonSerializer进行 ...

4. CentOS7配置Nodejs环境安装记录

今天购买了阿里云服务器,系统选的是CentOS7,下面记录下在它上面安装Nodejs环境的过程,本次操作是直接连接的阿里云服务器的管理终端. 1.由于是纯净的环境,先通过以下命令安装nodejs编译及 ...

5. OpenJ_Bailian 2814 拨钟问题

总时间限制:  1000ms 内存限制:  65536kB 描述 有9个时钟,排成一个3*3的矩阵. |-------| |-------| |-------|| | | | | | ||---O | ...

6. 五、IO编程

input/output:输入.输出 Stream(流):Input Stream就是数据从外面(磁盘.网络)流进内存,Output Stream就是数据从内存流到外面去.(流:相当于管道) 由于CP ...

7. Win10系列：VC++ Direct3D模板介绍3

(4)Render函数 默认定义在CubeRenderer.cpp源文件中的Render函数用于绘制立体图形,此函数的实现代码如下所示: void CubeRenderer::Render() {   ...

8. 洛谷P1600 天天爱跑步（线段树合并）

小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 nn ...

9. Simple上网导航--静态版

现在的网址导航显然是一个针对小白用户的网页大全,新闻.笑话.视频.黄段子要什么有什么,一个网址导航竟然也要滑动好多页.其实80%的功能我都用不到,但是它们却时刻展现在我的眼前.所以我决定做一个简洁清晰 ...

10. C的动态链表建立

运用到的函数为: 动态内存分配函数malloc()              比如:char *name=(char *)malloc(20);  相当与c++的new关键字 动态内存释放函数free ...