2.8
poj 1321
不会搜索,好像暑假的时候做过,不过又忘干净了
照着八皇后写了半天,不对
回溯没有写到,还是不理解啊


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 int n,k; 8 char g[15][15]; 9 int ans; 10 int c[15]; 11 12 void dfs(int cur,int cnt){ 13 // printf("--cur = %d cnt = %d\n",cur,cnt); 14 if(cnt == k){ 15 ans++; 16 return; 17 } 18 if(cur == n+1) return; 19 for(int i = 1;i <= n;i++){ 20 if(c[i] || g[cur][i] == '.') continue; 21 c[i] = 1; 22 dfs(cur+1,cnt+1); 23 c[i] = 0; 24 } 25 dfs(cur+1,cnt); 26 return; 27 } 28 29 int main(){ 30 while(scanf("%d %d",&n,&k) != EOF){ 31 if(n == -1 && k == -1) break; 32 memset(c,0,sizeof(c)); 33 for(int i = 1;i <= n;i++) scanf("%s",g[i]+1); 34 ans = 0; 35 dfs(1,0); 36 printf("%d\n",ans); 37 } 38 return 0; 39 }
2.9
cf 625a A - Guest From the Past
比赛的时候想得很混乱,还是直接去模拟那样写的
一直想不清楚的地方是,最开始的 n 可不可以买一部分a 再买一部分 b,然后分别应该买多少瓶,什么时候取最大值
还是不是很懂


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long LL; 8 const int maxn = 5e5+5; 9 LL n; 10 LL a,b,c; 11 12 void solve(){ 13 LL l = n/a; 14 LL r; 15 if((n-b)>= (b-c)) r = (n-b)/(b-c)+1; 16 else r = n/b; 17 18 r += (n-r*b+c*r)/a; 19 printf("%I64d\n",max(l,r)); 20 } 21 22 int main(){ 23 while(scanf("%I64d %I64d %I64d %I64d",&n,&a,&b,&c) != EOF){ 24 solve(); 25 } 26 return 0; 27 }
hdu 5623 KK's Number
看的题解>_<
用dp[i] 表示取到前 i 个数的时候,先手能够得到的分数差的最大值


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn = 5e5+5; 8 int a[maxn],dp[maxn],n; 9 10 void solve(){ 11 sort(a+1,a+n+1); 12 dp[0] = 0; 13 for(int i = 1;i <= n;i++){ 14 dp[i] = max(a[i]-dp[i-1],dp[i-1]); 15 //printf("dp[%d] = %d\n",i,dp[i]); 16 } 17 printf("%d\n",dp[n]); 18 } 19 20 int main(){ 21 int T; 22 scanf("%d",&T); 23 while(T--){ 24 scanf("%d",&n); 25 for(int i = 1;i <= n;i++) scanf("%d",&a[i]); 26 solve(); 27 } 28 return 0; 29 }
hdu 1698 Just a Hook
一直嚷嚷着学线段树,可是一直都没有去学T_T
抄个板先,感觉还是没理解
第一道区间更新的题>_< /


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int INF = (1<<30)-1; 8 const int maxn = 5e5+5; 9 10 struct node{ 11 int l,r; 12 int sum,flag; 13 }t[maxn<<2]; 14 15 int tl,tr,tv; 16 17 void Build_tree(int p,int l,int r){ 18 t[p].l = l; 19 t[p].r = r; 20 t[p].sum = r-l+1; 21 t[p].flag = 0; 22 if(l == r) return; 23 int mid = (l+r)/2; 24 Build_tree(p<<1,l,mid); 25 Build_tree(p<<1|1,mid+1,r); 26 } 27 28 void Push_down(int p){ 29 int v = t[p].flag; 30 if(v){ 31 t[p<<1].flag = t[p<<1|1].flag = v; 32 t[p<<1].sum = v*(t[p<<1].r-t[p<<1].l+1); 33 t[p<<1|1].sum = v*(t[p<<1|1].r-t[p<<1|1].l+1); 34 t[p].flag = 0; 35 } 36 } 37 38 void Push_up(int p){ 39 t[p].sum = t[p<<1].sum + t[p<<1|1].sum; 40 } 41 42 void Update(int p,int l,int r){ 43 if(tl <= l && r <= tr){ 44 t[p].flag = tv; 45 t[p].sum = tv*(t[p].r-t[p].l+1); 46 return; 47 } 48 Push_down(p); 49 int mid = (l+r)/2; 50 if(tl <= mid) Update(p<<1,l,mid); 51 if(tr > mid) Update(p<<1|1,mid+1,r); 52 Push_up(p); 53 } 54 55 int main(){ 56 int T,n,q; 57 scanf("%d",&T); 58 int kase = 0; 59 while(T--){ 60 scanf("%d %d",&n,&q); 61 Build_tree(1,1,n); 62 while(q--){ 63 scanf("%d %d %d",&tl,&tr,&tv); 64 Update(1,1,n); 65 } 66 printf("Case %d: The total value of the hook is %d.\n",++kase,t[1].sum); 67 } 68 return 0; 69 }
2.10
cf 279c 279C - Ladder


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn = 1e5+5; 8 int a[maxn],l[maxn],r[maxn],b[maxn]; 9 int n,m,ql,qr; 10 11 void solve(){ 12 memset(l,0,sizeof(l)); 13 memset(r,0,sizeof(r)); 14 l[1] = 1; 15 for(int i = 2;i <= n;i++){ 16 if(a[i] <= a[i-1]) l[i] = l[i-1]+1; 17 else l[i] = 1; 18 } 19 for(int i = 1;i <= n;i++) b[i] = a[n-i+1]; 20 r[1] = 1; 21 for(int i = 1;i <= n;i++){ 22 if(b[i] <= b[i-1]) r[i] = r[i-1]+1; 23 else r[i] = 1; 24 } 25 for(int i = 1;i <= n;i++) b[i] = r[n-i+1]; 26 for(int i = 1;i <= n;i++) r[i] = b[i]; 27 /* for(int i = 1;i <= n;i++){ 28 printf("l[%d] = %d r[%d] = %d\n",i,l[i],i,r[i]); 29 }*/ 30 for(int i = 1;i <= m;i++){ 31 scanf("%d %d",&ql,&qr); 32 if((r[ql]+ql-1) >= (qr-l[qr]+1)) puts("Yes"); 33 else puts("No"); 34 } 35 36 } 37 38 int main(){ 39 while(scanf("%d %d",&n,&m) != EOF){ 40 for(int i = 1;i <= n;i++) scanf("%d",&a[i]); 41 solve(); 42 } 43 return 0; 44 }
2.11
补题
cf 622 c Not Equal on a Segment
看到这题的第一眼,想到“区间查询不修改” ,用莫队哇,,可是不懂怎么转移啊--gg
l[i] 表示与a[i] 相同的最多能够延伸的长度


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn = 2e5+5; 8 int a[maxn],n,m,l[maxn]; 9 int ql,qr,x,b[maxn]; 10 11 void solve(){ 12 memset(l,0,sizeof(l)); 13 l[n] = 1; 14 for(int i = n-1;i >= 1;i--){ 15 if(a[i] == a[i+1]) l[i] = l[i+1]+1; 16 else l[i] = 1; 17 } 18 // for(int i = 1;i <= n;i++) printf("l[%d] = %d\n",i,l[i]); 19 20 for(int i = 1;i <= m;i++){ 21 scanf("%d %d %d",&ql,&qr,&x); 22 //printf("ql = %d qr = %d x = %d\n",ql,qr,x); 23 if(a[ql] != x){ 24 printf("%d\n",ql); 25 continue; 26 } 27 if(l[ql]+ql <= qr){ 28 printf("%d\n",l[ql]+ql); 29 continue; 30 } 31 puts("-1"); 32 } 33 } 34 35 int main(){ 36 while(scanf("%d %d",&n,&m) != EOF){ 37 for(int i = 1;i <= n;i++) scanf("%d",&a[i]); 38 solve(); 39 } 40 return 0; 41 }
话说这两天的太阳都超级好的哇(>_<)
hdu 5622 KK's Chemical
每一个连通块是 一颗树加上一条边,即一个环加上树边
先预处理出环的k染色的方案,然后树边的染色方案就是 (k-1)^(树边的数量)
先不理解的是,为什么会存在找不到环的情况
大概是,像这样的
0 1
1 0
2 1
0 --- 1 --- 2
0,1 之间本来是存在环的,但是因为存边的时候都是存的双向的边,所以找出来就是一条链了


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 typedef long long LL; 9 const int mod = 1e9+7; 10 const int maxn = 105; 11 int n,k,vis[maxn]; 12 LL dp[maxn][2]; 13 int sz,c; 14 vector<int> g[maxn]; 15 16 void dfs(int u,int fa,int dep){ 17 // printf("u = %d fa = %d dep = %d\n",u,fa,dep); 18 if(vis[u]){ 19 if(!sz) sz = dep-vis[u]; 20 return; 21 } 22 vis[u] = dep; 23 c++; 24 for(int i = 0;i < g[u].size();i++){ 25 int v = g[u][i]; 26 if(v == fa) continue; 27 dfs(v,u,dep+1); 28 } 29 } 30 31 void solve(){ 32 memset(vis,0,sizeof(vis)); 33 memset(dp,0,sizeof(dp)); 34 dp[1][1] = k; 35 for(int i = 2;i <= n;i++){ 36 dp[i][0] = (1LL*dp[i-1][0]*(k-2)%mod + 1LL*dp[i-1][1]*(k-1)%mod)%mod; 37 dp[i][1] = dp[i-1][0]; 38 } 39 /* for(int i = 1;i <= n;i++){ 40 printf("dp[%d][0] = %I64d dp[%d][1] = %I64d\n",i,dp[i][0],i,dp[i][1]); 41 }*/ 42 LL ans = 1; 43 for(int i = 0;i < n;i++){ 44 if(vis[i]) continue; 45 sz = c = 0; 46 dfs(i,-1,1); 47 // printf("sz = %d c = %d\n",sz,c); 48 if(sz == 0){ 49 ans = (1LL*ans*k)%mod; 50 c--; 51 } 52 else{ 53 ans = (1LL*ans*dp[sz][0])%mod; 54 } 55 c = c-sz; 56 while(c){ 57 ans = (1LL*ans*(k-1))%mod; 58 c--; 59 } 60 } 61 printf("%I64d\n",ans); 62 } 63 64 int main(){ 65 int T; 66 scanf("%d",&T); 67 while(T--){ 68 scanf("%d %d",&n,&k); 69 for(int i = 0;i < n;i++) g[i].clear(); 70 int v; 71 for(int i = 0;i < n;i++){ 72 scanf("%d",&v); 73 g[i].push_back(v); 74 g[v].push_back(i); 75 } 76 solve(); 77 } 78 return 0; 79 }
2.12
2.13
cf 514 c C - Watto and Mechanism
不懂字符串 哈希的时候 ,mod 和seed该怎么取


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<set> 6 using namespace std; 7 8 typedef long long LL; 9 const LL mod = 1e12+7; 10 int n,m; 11 const int maxn = 5e6+5; 12 char s[maxn],t[maxn],ct[maxn]; 13 set<LL> b; 14 LL p[maxn]; 15 16 void init(){ 17 p[0] = 1; 18 for(int i = 1;i < maxn;i++) p[i] = (p[i-1]*26)%mod; 19 } 20 21 LL Hash(char *s){ 22 LL res = 0; 23 int len = strlen(s); 24 for(int i = 0;i < len;i++) 25 res = (res*26+s[i])%mod; 26 return res; 27 } 28 int ok(char *t){ 29 LL tmp = Hash(t); 30 int len = strlen(t); 31 for(int i = 0;i < len;i++){ 32 for(int k = 0;k < 3;k++){ 33 if(k+'a' == t[i]) continue; 34 LL c = k+'a'-t[i]; 35 c = c * p[len-i-1]; 36 LL now = ((c + tmp)%mod+mod)%mod; 37 if(b.find(now) != b.end()) return 1; 38 } 39 } 40 return 0; 41 } 42 43 int main(){ 44 init(); 45 while(scanf("%d %d",&n,&m) != EOF){ 46 for(int i = 1;i <= n;i++){ 47 scanf("%s",s); 48 b.insert(Hash(s)); 49 } 50 for(int i = 1;i <= m;i++){ 51 scanf("%s",t); 52 if(ok(t)) puts("YES"); 53 else puts("NO"); 54 } 55 } 56 return 0; 57 }
cf 518 e Arthur and Questions
给出 n 个数,其中有些数的大小不确定,并且满足每连续k个是严格递增的
确定 这些 不确定的数,并且使得 sum(|a[i]|) 最小
------------------------------------------------------------------------------
完全不知道该咋做----
化简一下不等式可以得到
a1 < ak+1 < a2k+1 < ----
a2 < ak+2 < a2k+2 < ----
然后就只需要分别满足这 k 个子数列严格递增就好
如果 问号 的两端同号,就从 更大的那个数 挨个填下来
如果问号的两端异号的话,想的是要更靠近0来填,可是不懂个数该怎么分配
然后题解算了一个区间就可以了----虽然说画几个例子可以理解,可是还是不能算懂了的说啊


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn = 5e5+5; 8 int a[maxn],n,k; 9 const int INF = (1<<30)-1; 10 11 void solve(){ 12 int cnt = 0,pos = -INF; 13 for(int i = n+1;i <= n+k;i++) a[i] = INF+1; 14 for(int i = 1;i <= k;i++){ 15 cnt = 0;pos = -INF; 16 for(int j = i;j <= n+k;j+=k){ 17 if(a[j] == INF) cnt++; 18 else{ 19 printf("a[%d] = %d pos = %d cnt = %d\n",j,a[j],pos,cnt); 20 if(a[j]-pos <= cnt){ 21 puts("Incorrect sequence"); 22 return; 23 } 24 int st = max(pos+1,min(a[j]-cnt,-cnt/2)); 25 for(int z = cnt;z >= 1;z--){ 26 a[j-z*k] = st; 27 st++; 28 } 29 pos = a[j]; 30 cnt = 0; 31 } 32 } 33 } 34 for(int i = 1;i <= n;i++) printf("%d ",a[i]); 35 printf("\n"); 36 } 37 38 int main(){ 39 while(scanf("%d %d",&n,&k) != EOF){ 40 char s[5]; 41 for(int i = 1;i <= n;i++){ 42 scanf("%s",s); 43 if(s[0] == '?') a[i] = INF; 44 else sscanf(s, "%d", &a[i]); 45 } 46 // for(int i = 1;i <= n;i++) printf("%d ",a[i]); 47 solve(); 48 } 49 return 0; 50 }
2.14
hdu 5627 Clarke and MST
从高位到低位依次看能不能形成一颗生成树


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long LL; 8 const int maxn = 3e5+5; 9 int n,m,fa[maxn]; 10 11 int Find(int x){return fa[x] == x? x:fa[x] = Find(fa[x]);} 12 13 void init(){ 14 for(int i = 1;i <= n;i++) fa[i] = i; 15 } 16 17 struct Edge{ 18 int u,v,cost; 19 }e[maxn]; 20 21 void solve(){ 22 int ans = 0; 23 for(int k = 30;k >= 0;k--){ 24 ans += (1<<k); 25 int cnt = n; 26 init(); 27 for(int i = 1;i <= m;i++){ 28 if(e[i].cost & ans){ 29 // printf("-- k = %d i = %d\n",k,i); 30 int x = Find(e[i].u); 31 int y = Find(e[i].v); 32 if(x != y){ 33 fa[x] = y; 34 cnt--; 35 } 36 if(cnt == 1) break; 37 } 38 } 39 if(cnt != 1) ans -= (1<<k); 40 } 41 printf("%d\n",ans); 42 } 43 44 int main(){ 45 int T; 46 scanf("%d",&T); 47 while(T--){ 48 scanf("%d %d",&n,&m); 49 for(int i = 1;i <= m;i++) scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].cost); 50 solve(); 51 } 52 return 0; 53 }
hdu 5624 KK's Reconstruction
枚举的


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 const int maxn = 5e5+5; 9 int n,m,p[maxn]; 10 11 struct Edge{ 12 int u,v,cost; 13 }e[maxn]; 14 15 int cmp(Edge n1,Edge n2){ 16 return n1.cost < n2.cost; 17 } 18 19 void init(){ 20 for(int i = 1;i <= n;i++) p[i] = i; 21 } 22 23 int Find(int x){ 24 return p[x] == x ? x:p[x] = Find(p[x]); 25 } 26 27 void solve(){ 28 sort(e+1,e+m+1,cmp); 29 int res = 2e9+7; 30 for(int i = 1;i <= m;i++){ 31 init(); 32 int cnt = n,maxx = 0; 33 for(int j = i;j <= m;j++){ 34 int x = Find(e[j].u); 35 int y = Find(e[j].v); 36 if(x != y){ 37 p[x] = y; 38 cnt--; 39 maxx = max(maxx,e[j].cost); 40 } 41 if(cnt == 1) break; 42 } 43 if(cnt == 1){ 44 res = min(res,maxx-e[i].cost); 45 } 46 } 47 if(res == 2e9+7) puts("-1"); 48 else printf("%d\n",res); 49 } 50 51 int main(){ 52 int T; 53 scanf("%d",&T); 54 while(T--){ 55 scanf("%d %d",&n,&m); 56 for(int i = 1;i <= m;i++){ 57 scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].cost); 58 } 59 solve(); 60 } 61 return 0; 62 }
poj 3468 3468
稍微换了一下线段树的写法^w^


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long LL; 8 const int maxn = 5e5+5; 9 int a[maxn],n,m; 10 int ql,qr,qv; 11 LL t[maxn],add[maxn]; 12 int L[maxn],R[maxn]; 13 14 void Push_up(int o){ 15 t[o] = t[o<<1] + t[o<<1|1]; 16 } 17 18 void Build(int o,int l,int r){ 19 L[o] = l; 20 R[o] = r; 21 if(l == r){ 22 t[o] = a[l]; 23 return; 24 } 25 int mid = (l+r)/2; 26 Build(o<<1,l,mid); 27 Build(o<<1|1,mid+1,r); 28 Push_up(o); 29 } 30 31 void Push_down(int o){ 32 if(add[o]){ 33 add[o<<1] += add[o]; 34 add[o<<1|1] += add[o]; 35 t[o<<1] += add[o]*(R[o<<1]-L[o<<1]+1); 36 t[o<<1|1] += add[o]*(R[o<<1|1]-L[o<<1|1]+1); 37 add[o] = 0; 38 } 39 } 40 41 void Update(int o,int l,int r){ 42 if(ql <= l && r <= qr){ 43 add[o] += 1LL*qv; 44 t[o] += 1LL*qv*(R[o]-L[o]+1); 45 return; 46 } 47 Push_down(o); 48 int mid = (l+r)/2; 49 if(ql <= mid) Update(o<<1,l,mid); 50 if(qr > mid) Update(o<<1|1,mid+1,r); 51 Push_up(o); 52 } 53 54 LL Query(int o,int l,int r){ 55 if(ql <= l && r <= qr){ 56 return t[o]; 57 } 58 Push_down(o); 59 int mid = (l+r)/2; 60 LL res = 0; 61 if(ql <= mid) res += Query(o<<1,l,mid); 62 if(qr > mid) res += Query(o<<1|1,mid+1,r); 63 return res; 64 } 65 66 int main(){ 67 while(scanf("%d %d",&n,&m) != EOF){ 68 for(int i = 1;i <= n;i++) scanf("%d",&a[i]); 69 memset(add,0,sizeof(add)); 70 Build(1,1,n); 71 char s[5]; 72 for(int i = 1;i <= m;i++){ 73 scanf("%s",s); 74 if(s[0] == 'Q'){ 75 scanf("%d %d",&ql,&qr); 76 printf("%I64d\n",Query(1,1,n)); 77 } 78 else{ 79 scanf("%d %d %d",&ql,&qr,&qv); 80 Update(1,1,n); 81 } 82 } 83 } 84 return 0; 85 }
其实本来还是用之前的结构体那样写的,可是一直wawawawawa T_T
改了两天改不出来T_T
于是换了个写法,写完了,然后找到之前那个哪儿错了TwT