码迷,mamicode.com
首页 > 其他好文 > 详细

省选模拟6&7

时间:2020-01-14 18:58:28      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:min   ios   tor   closed   线段树   header   状压   signed   git   

因为改题太慢,两篇总结合一块写了。

馍旎6:

抄了一套UR(的题目

A. Yist

根号算法。

首先判-1即为判断是否有一个点能对其他点作贡献,且不存在于s序列中。

考虑单个点的贡献,假如第一轮贡献为$a$,之后每一轮的的贡献即为$a*2^{cnt}$

cnt为这个点在序列中出现的次数。然后这玩意拿等比数列求和就可以了。

然后出题人随便造个菊花图就能卡死你。

考虑根号算法,按每个点度数是否大于$\sqrt{n}$分为大点和小点。

对于每个大点,统计时暴力扫与它相连的大点统计贡献,

大点同时累计自己对周围小点的贡献

小点暴力扫所有出边统计贡献,同时接受大点贡献

技术图片
 1 #include<bits/stdc++.h>
 2 #define N 400050
 3 #define pb push_back
 4 const int mod=998244353,inv2=499122177;
 5 using namespace std;
 6 int s[N],n,m,k;
 7 int w[N],d[N];
 8 int a[N],ts[N],val[N];
 9 vector<int>v[N],c[N];
10 inline int qpow(int d,int z){
11     int ret=1;
12     for(;z;z>>=1,d=1ll*d*d%mod)
13         if(z&1)ret=1ll*ret*d%mod;
14     return ret;
15 }
16 inline bool judge(){
17     static bool pd[N];
18     memset(pd,false,sizeof(pd));
19     for(int i=1;i<=k;++i)pd[s[i]]=1;
20     for(int i=1;i<=n;++i)
21         for(int j=v[i].size()-1;~j;--j)
22             if(pd[i]&&!pd[v[i][j]]&&w[v[i][j]])
23                 return true;
24     return false;
25 }
26 bool cmp(const int &a,const int &b){
27     return v[a].size()>v[b].size();
28 }
29 int main(){
30     for(int i=1;i<=n;++i){
31         v[i].clear();c[i].clear();
32         ts[i]=1;a[i]=val[i]=d[i]=0;
33     }
34     if(scanf("%d%d%d",&n,&m,&k)==EOF)return 0;
35     for(int i=1;i<=n;++i){
36         scanf("%d",&w[i]);
37         v[i].clear();c[i].clear();
38         ts[i]=1,a[i]=val[i]=d[i]=0;
39     }
40     for(int i=1;i<=k;++i)scanf("%d",&s[i]);
41     for(int i=1,x,y;i<=m;++i){
42         scanf("%d%d",&x,&y);
43         v[x].pb(y);v[y].pb(x);
44     }
45     if(judge()){puts("-1");return main();}
46     const int sq=sqrt(n);
47     for(int i=1;i<=n;++i){
48         sort(v[i].begin(),v[i].end(),cmp);
49         d[i]=v[i].size()>=sq?1:0;
50     }
51     for(int i=1;i<=n;++i)
52         if(!d[i]){
53             for(int j=0,sz=v[i].size();j<sz&&d[v[i][j]];++j)
54                 c[i].pb(0);
55         }
56     int ans=0;
57     
58     for(int i=1,g;i<=k;++i){
59         g=s[i];ts[g]<<=1;
60         if(ts[g]>=mod)ts[g]-=mod;
61         if(d[g]){
62             ++val[g];
63             for(int j=0,sz=v[g].size();j<sz&&d[v[g][j]];++j)
64                 (a[v[g][j]]+=w[v[g][j]])%=mod;
65         }
66         else{
67             for(int j=0,sz=v[g].size();j<sz;++j){
68                 (a[v[g][j]]+=w[v[g][j]])%=mod;
69                 if(d[v[g][j]]){
70                     (a[g]+=1ll*w[g]*(val[v[g][j]]-c[g][j])%mod)%=mod;
71                     c[g][j]=val[v[g][j]];
72                 }
73             }
74         }
75         w[g]=1ll*w[g]*inv2%mod;
76     }
77     for(int g=1;g<=n;++g)
78         if(!d[g]){
79             for(int j=0,sz=v[g].size();j<sz&&d[v[g][j]];++j)
80                 (a[g]+=1ll*w[g]*(val[v[g][j]]-c[g][j])%mod)%=mod;
81         }
82     for(int i=1;i<=n;++i){
83         ans+=1ll*a[i]*ts[i]%mod*qpow(ts[i]-1,mod-2)%mod;
84         if(ans>=mod)ans-=mod;
85     }
86     cout<<ans<<endl;
87     return main();
88 }
View Code

B. Ernd

$SAM+dp$

在串前加字符相当于在$parent_tree$上走,在串后加字符相当于在$SAM$上走。

发现对于$parent_tree$上一个节点,一定是把它先走到当前点的最大长度再转移。

拓扑dp,最后输出$dp[las]$

技术图片
 1 #include<bits/stdc++.h>
 2 #define N 400050
 3 #define ull unsigned long long
 4 using namespace std;
 5 int n,f[N];
 6 int du[N];
 7 long long dp[N],ans;
 8 char s[N];
 9 int tot=1,las=1;
10 int he[N],ne[N],to[N],cnt;
11 inline void addedge(int x,int y){
12     to[++cnt]=y;ne[cnt]=he[x];he[x]=cnt;
13 }
14 struct node{
15     int len,fa;
16     int ch[26];
17 }tr[N];
18 inline void add(int c){
19     int np=++tot,p=las;las=np;f[np]=1;
20     tr[np].len=tr[p].len+1;
21     for(;p&&!tr[p].ch[c];p=tr[p].fa)tr[p].ch[c]=np;
22     if(!p)return tr[np].fa=1,void();
23     int q=tr[p].ch[c];
24     if(tr[q].len==tr[p].len+1)return tr[np].fa=q,void();
25     int nq=++tot;tr[nq]=tr[q];
26     tr[nq].len=tr[p].len+1;
27     tr[q].fa=tr[np].fa=nq;
28     for(;p&&tr[p].ch[c]==q;p=tr[p].fa)tr[p].ch[c]=nq;
29 }
30 inline void tope(){
31     for(int i=1;i<=tot;++i)
32         for(int j=0;j<26;++j)
33             ++du[tr[i].ch[j]];
34     queue<int>q;q.push(1);
35     while(q.size()){
36         int g=q.front();q.pop();
37 //        printf("f[%d]=%d\n",g,f[g]);
38         dp[g]=max(dp[g],dp[tr[g].fa]+f[g]*(tr[g].len-tr[tr[g].fa].len));
39         for(int i=0,t;i<26;++i){
40             t=tr[g].ch[i];if(!t)continue;
41             dp[t]=max(dp[t],dp[g]+1ll*f[t]*(tr[t].len-tr[g].len));
42             --du[t];
43             if(!du[t])q.push(t);
44         }
45     }
46     ans=dp[las];
47 }
48 inline void dfs(int g){
49     for(int i=he[g];i;i=ne[i])
50         dfs(to[i]),f[g]+=f[to[i]];
51 }
52 int main(){
53     scanf("%d%s",&n,s+1);
54     for(int i=1;i<=n;++i)add(s[i]-a);
55     for(int i=2;i<=tot;++i)addedge(tr[i].fa,i);
56     dfs(1);
57     tope();
58     cout<<ans<<endl;
59     return 0;
60 }
View Code

C. Sanrd

大神题,改了一下午加一晚上加一早上才改过来。

技术图片

其实还是挺好理解的,就是代码难打

技术图片
  1 #include<bits/stdc++.h>
  2 #define N 500050
  3 #define ull long long
  4 const int mod=998244353;
  5 using namespace std;
  6 int dp1[N],dp2[N],n,a[N],an1,an2,pr[N][2],pre[N];
  7 ull f[N],f2[N],al,w[N][2];
  8 struct BIT{
  9     int ct[N],po[N];
 10     inline void clear(){
 11         memset(ct,0,sizeof(int)*(n+1));
 12         memset(po,0,sizeof(int)*(n+1));
 13     }
 14     inline void add(int x,int v,int id=0){
 15         while(x){
 16             if(v>ct[x])
 17                 ct[x]=v,po[x]=id;
 18             x-=x&-x;
 19         }
 20     }
 21     inline int ask(int x){
 22         int ret=0;
 23         while(x<=n)
 24             ret=max(ret,ct[x]),x+=x&-x;
 25         return ret;
 26     }
 27     inline int ask2(int x){
 28         int ret=0,r2=0;
 29         while(x<=n){
 30             if(ct[x]>ret)ret=ct[x],r2=po[x];
 31             x+=x&-x;
 32         }
 33         return r2;
 34     }
 35 }b;
 36 struct BIT2{
 37     ull ct[N];int tim[N],cnt;
 38     inline void clear(){++cnt;}
 39     inline void add(int x,int v){
 40         while(x){
 41             if(tim[x]!=cnt)tim[x]=cnt,ct[x]=0;
 42             ct[x]+=v;x-=x&-x;
 43         }
 44     }
 45     inline ull ask(int x){
 46         ull ret=0;
 47         while(x<=n){
 48             if(tim[x]!=cnt)tim[x]=cnt,ct[x]=0;
 49             ret+=ct[x];
 50             x+=x&-x;
 51         }
 52         ret%=mod;
 53         return ret;
 54     }
 55 }b2;
 56 vector<int>v[N];
 57 #define pb push_back
 58 inline void init1(){
 59     b.clear();
 60     for(int i=1;i<=n;++i){
 61         dp2[i]=b.ask(a[i])+1;
 62         an2=max(an2,dp2[i]);
 63         b.add(a[i],dp2[i]);
 64         v[dp2[i]].push_back(i);
 65 //        printf("dp2[%d]=%d\n",i,dp2[i]);
 66     }
 67     for(int i=0,sz=v[an2].size();i<sz;++i)f[v[an2][i]]=1;
 68     for(int i=an2;i>1;--i){
 69         int j=v[i-1].size()-1,k=v[i].size()-1;
 70         b2.clear();
 71         while(j>=0){
 72             while(k>=0&&v[i][k]>v[i-1][j]){
 73                 b2.add(a[v[i][k]],f[v[i][k]]);
 74                 --k;
 75             }
 76             f[v[i-1][j]]=b2.ask(1)-b2.ask(a[v[i-1][j]]);
 77             if(f[v[i-1][j]]<0)f[v[i-1][j]]+=mod;
 78             --j;
 79         }
 80     }
 81 //    for(int i=1;i<=n;++i)printf("f[%d]=%lld f2:%lld\n",i,f[i],f2[i]);
 82     for(int i=0,sz=v[1].size();i<sz;++i)f2[v[1][i]]=1;
 83     for(int i=1;i<an2;++i){
 84         int j=0,k=0,sz=v[i].size(),sz2=v[i+1].size();
 85         b2.clear();
 86         while(j<sz2){
 87             while(k<sz&&v[i][k]<v[i+1][j]){
 88                 b2.add(a[v[i][k]],f2[v[i][k]]);
 89                 ++k;
 90             }
 91             f2[v[i+1][j]]=b2.ask(a[v[i+1][j]]);
 92             f[v[i+1][j]]*=f2[v[i+1][j]];
 93             f[v[i+1][j]]%=mod;
 94             ++j;
 95         }
 96     }
 97     for(int j=0,sz=v[an2].size();j<sz;++j)al+=f[v[an2][j]];
 98     al%=mod;
 99 //    for(int i=1;i<=n;++i)printf("f[%d]=%lld f2:%lld\n",i,f[i],f2[i]);
100 //    cout<<"al:"<<al<<endl;
101 }
102 int pd[N];
103 struct BIT3{
104     int ct[N];
105     inline void add(int x,int v){
106         while(x<=n){
107             if(v>ct[x])ct[x]=v;
108             x+=x&-x;
109         }
110     }
111     inline int ask(int x){
112         int ret=0;
113         while(x)ret=max(ret,ct[x]),x-=x&-x;
114         return ret;
115     }
116 }b3;
117 struct BIT4{
118     int q[N][2],ct[N];
119     ull qq[N][2];
120     inline void init(){
121         for(int i=1;i<=n;++i)qq[i][0]=qq[i][1]=q[i][0]=q[i][1]=-1;
122     }
123     inline void add(int i){
124         int x=a[i];
125         while(x<=n){
126             if(dp1[i]>ct[x]){
127                 ct[x]=dp1[i];
128                 q[x][0]=qq[x][0]=q[x][1]=qq[x][1]=-1;
129             }
130             if(ct[x]==dp1[i]&&qq[x][0]<0&&w[i][0]>=0){
131                 q[x][0]=i;
132                 qq[x][0]=w[i][0];
133                 if(w[i][1]>=0){
134                     q[x][1]=i;
135                     qq[x][1]=w[i][1];
136                 }
137             }
138             else if(ct[x]==dp1[i]&&qq[x][1]<0){
139                 if(w[i][0]>=0&&w[i][0]!=qq[x][0]){
140                     q[x][1]=i;
141                     qq[x][1]=w[i][0];
142                 }
143                 if(w[i][1]>=0&&w[i][1]!=qq[x][0]){
144                     q[x][1]=i;
145                     qq[x][1]=w[i][1];
146                 }
147             }
148             x+=x&-x;
149         }
150     }
151     inline void ask(int i){
152         int x=a[i];
153         while(x){
154             if(ct[x]==dp1[i]-1&&w[i][0]<0&&qq[x][0]>=0){
155                 pr[i][0]=q[x][0];
156                 w[i][0]=qq[x][0];
157                 if(qq[x][1]>=0){
158                     pr[i][1]=q[x][1];
159                     w[i][1]=qq[x][1];
160                 }
161             }
162             else if(ct[x]==dp1[i]-1&&w[i][1]<0&&qq[x][0]>=0){
163                 if(qq[x][0]>=0&&qq[x][0]!=w[i][0]){
164                     pr[i][1]=q[x][0];
165                     w[i][1]=qq[x][0];
166                 }
167                 if(qq[x][1]>=0&&qq[x][1]!=w[i][0]){
168                     pr[i][1]=q[x][1];
169                     w[i][1]=qq[x][1];
170                 }
171             }
172             x-=x&-x;
173         }
174     }
175 }b4;
176 inline void init2(){
177     b4.init();
178     for(int i=1;i<=n;++i){
179         dp1[i]=b3.ask(a[i])+1;
180         an1=max(an1,dp1[i]);
181         b3.add(a[i],dp1[i]);
182 //        printf("dp1[%d]=%d\n",i,dp1[i]);
183     }
184     for(int i=1;i<=n;++i){
185         w[i][0]=w[i][1]=-1;
186         //if(dp1[i]!=1)
187         b4.ask(i);
188         if(w[i][0]>=0||dp1[i]==1){
189             w[i][0]+=f[i];
190             if(dp1[i]==1)++w[i][0];
191         }
192         if(w[i][1]>=0)w[i][1]+=f[i];
193         w[i][0]%=mod;w[i][1]%=mod;
194 //        printf("i:%d w0:%lld w1:%lld p0:%d p1:%d\n",i,w[i][0],w[i][1],pr[i][0],pr[i][1]);
195         b4.add(i);
196     }
197 }
198 inline void dfs2(int g){
199     if(!g)return;dfs2(pre[g]);
200     printf("%d ",g);
201 }
202 inline void getans(){
203     b.clear();
204     printf("%d\n",an1);
205     for(int i=1;i<=n;++i){
206         dp2[i]=0;
207         if(pd[i]){
208             printf("%d ",i);
209             continue;
210         }
211         dp2[i]=b.ask(a[i])+1;
212         pre[i]=b.ask2(a[i]);
213         b.add(a[i],dp2[i],i);
214 //        printf("pre[%d]=%d dp2:%d\n",i,pre[i],dp2[i]);
215     }
216     printf("\n%d\n",an2);
217     for(int i=1;i<=n;++i)
218         if(dp2[i]==an2)return dfs2(i);
219 }
220 inline void dfs(int g,ull t){
221     if(!g)return getans();
222     pd[g]=1;
223     if((t+w[g][0])%mod!=al)dfs(pr[g][0],(t+f[g])%mod);
224     else dfs(pr[g][1],(t+f[g])%mod);
225 }
226 int main(){
227 //    freopen("sanrd2.in","r",stdin);freopen("my.out","w",stdout);
228     scanf("%d",&n);
229     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
230     init1();init2();
231     memset(pd,0,sizeof(int)*(n+1));
232     for(int i=1;i<=n;++i){
233 //        cout<<i<<" "<<w[i][0]<<" "<<w[i][1]<<endl;
234         if(dp1[i]==an1){
235             if(w[i][0]!=-1&&w[i][0]!=al){
236                 pd[i]=1;dfs(pr[i][0],f[i]);
237                 return 0;
238             }
239             if(w[i][1]!=-1&&w[i][1]!=al){
240                 pd[i]=1;dfs(pr[i][1],f[i]);
241                 return 0;
242             }
243         }
244     }
245     puts("-1");return 0;
246 }
View Code

馍旎7:

A. 翻转硬币/星空

原来写过一遍的题,然而也忘得差不多了。

用到了差分的思想。

考虑维护原01序列的差分序列。

则原先的区间操作对应新的对有距离限制的两个点取反,

转化为求最少多少次操作使得差分序列全为0。

然后对每个为1点求出与其它为1的点的距离。

然后跑状压dp就可以了。

技术图片
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<queue>
 5 #define reg register
 6 #define N 1100000
 7 using namespace std;
 8 int m,n,k;
 9 int a[120];
10 int b[120];
11 int pos[N];
12 int g1[N];
13 int g2[N];
14 int dis[N][2];
15 int w[1<<20];
16 int dp[1<<20];
17 void bfs()
18 {
19     memset(w,0x3f,sizeof(w));
20     a[0]=0;
21     for(int i=1;i<=n;++i)
22         if(g2[i])a[++a[0]]=i,pos[i]=a[0];
23     queue<int>q;
24     int al,g,y;
25     for(int i=1;i<=a[0];++i)
26     {
27         al=1;
28         q.push(a[i]);dis[a[i]][0]=dis[a[i]][1]=0;
29         while(al<a[0]&&q.size())
30         {
31             g=q.front();q.pop();
32             for(int j=1;j<=m;++j)
33             {
34                 if(g-b[j]>0&&dis[g-b[j]][0]<i){
35                     y=g-b[j];
36                     dis[y][0]=i;
37                     dis[y][1]=dis[g][1]+1;
38                     if(pos[y]&&y!=a[i])
39                         w[(1<<i-1)|(1<<pos[y]-1)]=dis[y][1];
40                     else
41                     q.push(y);
42                 }
43                 if(g+b[j]<=n&&dis[g+b[j]][0]<i){
44                     y=g+b[j];
45                     dis[y][0]=i;
46                     dis[y][1]=dis[g][1]+1;
47                     if(pos[y]&&y!=a[i])
48                         w[(1<<i-1)|(1<<pos[y]-1)]=dis[y][1];
49                     else
50                     q.push(y);
51                 }
52             }
53         }
54         while(q.size())q.pop();
55     }
56 }
57 void work()
58 {
59     memset(dp,0x3f,sizeof(dp));
60     const int maxn=1<<a[0];dp[maxn-1]=0;
61     reg int t1,t2;
62     for(int i=maxn-1;i;--i)
63         for(int j=i;j;j-=j&-j){
64             t1=j&-j;
65             for(int o=j-(j&-j);o;o-=o&-o){
66                 t2=o&-o;
67                 dp[i^t1^t2]=min(dp[i^t1^t2],dp[i]+w[t1|t2]);
68             }
69         }
70     if(dp[0]>5000000)dp[0]=-1;
71     cout<<dp[0]<<endl;
72 }
73 int main()
74 {
75     scanf("%d%d%d",&n,&k,&m);
76     for(int i=1;i<=k;++i)
77         scanf("%d",&a[i]),g1[a[i]]=1;
78     ++n;
79     for(int i=1;i<=m;++i)
80         scanf("%d",&b[i]);
81     for(int i=1;i<=n;++i)
82         g2[i]=g1[i]^g1[i-1];
83     bfs();
84     work();
85     return 0;
86 }
View Code

B. 回文子串

其实还是比较水的一道题,除了样例弱一点没啥

然后维护答案可以用分快or线段树or树状数组。

求回文串可以用$PAM or Manacher or hash$

再加一个对拍就A了。上面的可以没有,但对拍必须有

技术图片
  1 #include<bits/stdc++.h>
  2 #define N 50050
  3 #define ull unsigned long long
  4 using namespace std;
  5 int bl[N];
  6 char s[N];
  7 int n,sq,m,K;
  8 ull po[N],hs[N],hs2[N];
  9 const ull P=131;
 10 inline void geths(int l,int r){
 11     hs[l-1]=hs[r+1]=hs2[l-1]=hs2[r+1]=0;
 12     for(int i=l;i<=r;++i)hs[i]=hs[i-1]*P+s[i];
 13     for(int i=r;i>=l;--i)hs2[i]=hs2[i+1]*P+s[i];
 14 }
 15 struct seg1{
 16     int tag[N<<2];
 17     inline void down(int g){
 18         tag[g<<1]=tag[g<<1|1]=tag[g];
 19         tag[g]=0;
 20     }
 21     inline void change(int g,int l,int r,int x,int y,int c){
 22         if(l>y||r<x)return;
 23         if(l>=x&&r<=y){tag[g]=c;return;}
 24         const int m=l+r>>1;
 25         if(tag[g])down(g);
 26         change(g<<1,l,m,x,y,c);change(g<<1|1,m+1,r,x,y,c);
 27     }
 28     inline void getstr(int g,int l,int r,int x,int y){
 29         if(l>y||r<x)return;
 30         if(l==r){if(tag[g])s[l]=tag[g];return;}
 31         const int m=l+r>>1;if(tag[g])down(g);
 32         getstr(g<<1,l,m,x,y);getstr(g<<1|1,m+1,r,x,y);
 33     }
 34 }str;
 35 struct seg2{
 36     int sum[N<<2],tag[N<<2];
 37     inline void upd(int g){
 38         sum[g]=sum[g<<1]+sum[g<<1|1];
 39     }
 40     inline void down(int g,int l,int m,int r){
 41         tag[g<<1]=tag[g<<1|1]=tag[g];
 42         if(tag[g]==1)sum[g<<1]=m-l+1,sum[g<<1|1]=r-m;
 43         else sum[g<<1]=sum[g<<1|1]=0;
 44         tag[g]=0;
 45     }
 46     inline void change(int g,int l,int r,int x,int y,int v){
 47         if(l>y||r<x)return;
 48         if(l>=x&&r<=y){
 49             sum[g]=v>0?r-l+1:0;
 50             tag[g]=v;
 51             return;
 52         }
 53         const int m=l+r>>1;
 54         if(tag[g])down(g,l,m,r);
 55         change(g<<1,l,m,x,y,v);change(g<<1|1,m+1,r,x,y,v);
 56         upd(g);
 57     }
 58     inline int ask(int g,int l,int r,int x,int y){
 59         if(l>y||r<x)return 0;
 60         if(l>=x&&r<=y)return sum[g];
 61         const int m=l+r>>1;
 62         if(tag[g])down(g,l,m,r);
 63         return ask(g<<1,l,m,x,y)+ask(g<<1|1,m+1,r,x,y);
 64     }
 65 }tr[52];
 66 inline void init(){
 67     geths(1,n);
 68     for(int len=2;len<=K;++len){
 69         for(int i=len,j;i<=n;++i){
 70             j=i-len+1;
 71             if(hs[i]-hs[j-1]*po[len]==hs2[j]-hs2[i+1]*po[len])
 72                 tr[len].change(1,1,n,i,i,1);
 73         }
 74     }
 75 }
 76 inline void work1(int l,int r,int c){
 77     str.change(1,1,n,l,r,c);
 78     for(int len=2;len<=K;++len)
 79         tr[len].change(1,1,n,l+len-1,r,1);
 80     for(int len=2;len<=K;++len)
 81         tr[len].change(1,1,n,r+1,min(n,r+len-1),-1),
 82         tr[len].change(1,1,n,l,min(l+len-2,n),-1);
 83     int lm,rm;
 84 
 85     lm=max(r-K+2,1);rm=min(r+K,n);
 86     str.getstr(1,1,n,lm,rm);
 87     geths(lm,rm);
 88 //    printf("lm:%d rm:%d\n",lm,rm);
 89     for(int len=2;len<=K;++len){
 90         for(int i=r+1,j;i<=rm;++i){
 91             j=i-len+1;
 92             if(j>r)break;
 93             if(j<=0)continue;
 94 //            puts("yes1");
 95             if(hs[i]-hs[j-1]*po[len]==hs2[j]-hs2[i+1]*po[len])
 96                 tr[len].change(1,1,n,i,i,1);//,cout<<i<<" ri "<<len<<endl;
 97         }
 98     }
 99     lm=max(l-K,1);rm=min(l+K-1,n);
100     rm=min(rm,r);
101     str.getstr(1,1,n,lm,rm);
102     geths(lm,rm);
103 //    printf("lm:%d rm:%d\n",lm,rm);
104     for(int len=2;len<=K;++len){
105         for(int i=l,j;i<=rm;++i){
106             j=i-len+1;
107             if(j>=l)break;if(j<=0)continue;
108 //            puts("yes2");
109             if(hs[i]-hs[j-1]*po[len]==hs2[j]-hs2[i+1]*po[len])
110                 tr[len].change(1,1,n,i,i,1);//,cout<<i<<" le "<<len<<endl;
111         }
112     }
113 //    cout<<tr[2].sum[1]<<" "<<tr[3].sum[1]<<endl;
114 }
115 inline int getans(int l,int r){
116     int ret=r-l+1;
117     for(int len=2;len<=K;++len)
118         ret+=tr[len].ask(1,1,n,l+len-1,r);
119     return ret;
120 }
121 int main(){
122     scanf("%s%d%d",s+1,&K,&m);
123     n=strlen(s+1);sq=sqrt(n)+1;
124     po[0]=1;for(int i=1;i<=n;++i)po[i]=po[i-1]*P;
125     init();
126     char S[3];
127     for(int i=1,op,x,y;i<=m;++i){
128 //        cout<<"i::"<<i<<endl;
129         scanf("%d",&op);
130         if(op==1){
131             scanf("%d%d%s",&x,&y,S);
132             work1(x,y,S[0]);
133         }
134         else{
135             scanf("%d%d",&x,&y);
136             printf("%d\n",getans(x,y));
137         }
138     }
139     return 0;
140 }
View Code

C. 最大价值

大神T3,%%%skyh考场切掉(然而没开long long 挂得还不如暴力xswl)

当所选序列确定以后,一定是按a从小到大放。

首先60分可以直接按a从小到大排序,然后大力dp。

然后满分可以康这位大神的博客

技术图片
 1 #include<bits/stdc++.h>
 2 #define N 300050
 3 #define LL long long
 4 using namespace std;
 5 struct node{
 6     LL a,b;
 7     friend bool operator <(const node &x,const node &y){
 8         return x.a==y.a?x.b<y.b:x.a<y.a;
 9     }
10 }q[N];
11 struct Splay{
12     LL val[N],tag[N];
13     int fa[N],ch[N][2],sz[N],rt,tot;
14     inline int Get(int x){return ch[fa[x]][1]==x;}
15     inline void upd(int g){sz[g]=sz[ch[g][0]]+sz[ch[g][1]]+1;}
16     inline void rotate(int x){
17         int y=fa[x],z=fa[y],p=Get(x),w=ch[x][p^1];
18         if(w)fa[w]=y;ch[y][p]=w;
19         if(z)ch[z][Get(y)]=x;fa[x]=z;
20         fa[y]=x;ch[x][p^1]=y;
21         upd(y);upd(x);
22     }
23     inline void push1(int g,LL v){if(!g||!v)return;val[g]+=v;tag[g]+=v;}
24     inline void down(int x){push1(ch[x][0],tag[x]),push1(ch[x][1],tag[x]);tag[x]=0;}
25     inline void pushall(int x){if(!x)return;down(x);}
26     inline void splay(int x){while(fa[x])rotate(x);rt=x;}
27     inline void insert(int i){
28         ++tot;sz[tot]=1;
29         if(!rt){rt=tot;val[rt]=q[i].b;return;}
30         LL a=q[i].a,b=q[i].b;
31         int x=rt,rk=0;
32         while(1){
33             down(x);
34             if(a*(rk+sz[ch[x][0]])+b>val[x]){
35                 if(ch[x][0])x=ch[x][0];
36                 else{ch[x][0]=tot;fa[tot]=x;break;}
37             }
38             else{
39                 rk+=sz[ch[x][0]]+1;
40                 if(ch[x][1])x=ch[x][1];
41                 else{ch[x][1]=tot;fa[tot]=x;break;}
42             }
43         }
44         val[tot]=a*rk+b;
45         splay(tot);push1(ch[rt][1],a);
46     }
47     inline void bl(int g,LL &ans){
48         down(g);
49         if(ch[g][0])bl(ch[g][0],ans);
50         ans+=val[g];
51         printf("%lld\n",ans);
52         if(ch[g][1])bl(ch[g][1],ans);
53     }
54 }s;
55 namespace ae86{
56     const int bufl=1<<15;
57     char buf[bufl],*s=buf,*t=buf;
58     inline int fetch(){
59         if(s==t){t=(s=buf)+fread(buf,1,bufl,stdin);if(s==t)return EOF;}
60         return*s++;
61     }
62     inline LL read(){
63         LL a=0,b=1,c=fetch();
64         while(!isdigit(c))b^=c==-,c=fetch();
65         while(isdigit(c))a=a*10+c-48,c=fetch();
66         return b?a:-a;
67     }
68 }
69 using ae86::read;
70 int n;
71 int main(){
72     n=read();
73     for(int i=1;i<=n;++i)q[i].a=read(),q[i].b=read();
74     sort(q+1,q+n+1);LL ans=0;
75     for(int i=1;i<=n;++i)s.insert(i);
76     s.bl(s.rt,ans);
77     return 0;
78 }
View Code

省选模拟6&7

标签:min   ios   tor   closed   线段树   header   状压   signed   git   

原文地址:https://www.cnblogs.com/loadingkkk/p/12193429.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!