寒假第五周 2.8 --- 2.14

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 }
View Code

 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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

话说这两天的太阳都超级好的哇(>_<)

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

其实本来还是用之前的结构体那样写的,可是一直wawawawawa T_T

改了两天改不出来T_T

于是换了个写法,写完了,然后找到之前那个哪儿错了TwT

 

转载于:https://www.cnblogs.com/wuyuewoniu/p/5184893.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值