2017.11.25NOIP提高组模拟赛A组

Posted _patrick

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017.11.25NOIP提高组模拟赛A组相关的知识,希望对你有一定的参考价值。

2017.11.25【NOIP提高组】模拟赛A组

T1 3467. 【NOIP2013模拟联考7】最长上升子序列(lis) 
T2 3468. 【NOIP2013模拟联考7】OSU!(osu) 
T3 3472. 【NOIP2013模拟联考8】匹配(match)

T1 有转移方程f[i]=max{f[j]}+1,a[j]<a[i]

可以用线段树+离散化维护这个方程,因为涉及以往状态可以用主席树维护

打太丑爆空间了

Code

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define fo(i,a,b) for(int i=a;i<=b;i++)
 6 #define fd(i,a,b) for(int i=a;i>=b;i--)
 7 #define fh(i,x) for(int i=head[x];i;i=next[i])
 8 typedef long long LL;
 9 inline int max(int x,int y){return (x<y)?y:x;}
10 inline int min(int x,int y){return (x<y)?x:y;}
11 inline int read() {
12     int x=0,f=1;char ch=getchar();
13     while(ch<0||ch>9)f=(ch==-)?-1:f,ch=getchar();
14     while(ch>=0&&ch<=9)x=x*10+(ch-0),ch=getchar();return f*x;
15 }
16 using namespace std;
17 const int N=500000+50;
18 int op[N],a[N],b[N],x[N],cnt1,now,ans,tot,ans1[N],q[N],tot1;
19 struct tree {
20     int l,r,mx;
21     tree *xl,*xr;
22     tree(){l=r=mx=0,xl=xr=NULL;}
23     void update() {
24         if(!xl&&!xr)return;
25         if(xl&&xr)mx=max(xl->mx,xr->mx);
26         else mx=(xl)?xl->mx:xr->mx;
27     }
28     int query(int L,int R) {
29         if(L>R)return 0;
30         if(l==L&&r==R)return mx;
31         int mid=(l+r)>>1;
32         int tx=0;
33         if(xl&&R<=mid)return xl->query(L,R);
34         if(xr&&l>mid)return xr->query(L,R);
35         else {
36             if(xl)tx=xl->query(L,mid);
37             if(xr)tx=max(tx,xr->query(mid+1,R));
38             return tx;
39         }
40     }
41     void add(int p,int val) {
42         if(l==r){mx=val;return;}
43         int mid=(l+r)>>1;
44         tree *tl=xl,*tr=xr;
45         if(p<=mid) {
46             xl=new tree;if(tl)xl->xl=tl->xl,xl->xr=tl->xr;
47             xl->l=l,xl->r=mid,xl->add(p,val);
48         } else {
49             xr=new tree;if(tr)xr->xl=tr->xl,xr->xr=tr->xr;
50             xr->l=mid+1,xr->r=r,xr->add(p,val);
51         }
52         update();
53     }
54 }*rt[N];
55 int main() {
56     freopen("lis.in","r",stdin),freopen("lis.out","w",stdout);
57     int n=read();
58     fo(i,1,n) {
59         op[i]=read();
60         if(op[i])x[i]=read();
61         else a[++cnt1]=b[cnt1]=read();
62     }
63     sort(b+1,b+1+cnt1);int cnt=unique(b+1,b+1+cnt1)-b-1;
64     fo(i,1,cnt1)a[i]=lower_bound(b+1,b+cnt+1,a[i])-b;
65     now=0,ans=0;
66     rt[0]=new tree,rt[0]->l=1,rt[0]->r=cnt;
67     fo(i,1,n) {
68         if(!op[i]) {
69             int t=0;tot1++;
70             if(rt[now])t=rt[now]->query(1,a[tot1]-1);
71             (rt[i]=new tree)->l=1,rt[i]->r=cnt;
72             if(rt[now])rt[i]->xl=rt[now]->xl,rt[i]->xr=rt[now]->xr;
73             rt[i]->add(a[tot1],t+1);
74             ans=max(ans,t+1);
75             q[i]=i,ans1[i]=ans;
76             now=i;
77         }
78         if(op[i]) {
79             now=x[i],ans=ans1[x[i]],rt[i]=rt[x[i]];
80             q[i]=x[i],ans1[i]=ans;
81         }
82     }
83     fo(i,1,n)printf("%d\n",ans1[i]);
84     return 0;
85 }

 

T2 如果把连续的一段 1,和这段两边的 0 作为一个整体,那么这些就是相互独立的。 分别计算每一个即可

用Dp优化这个做法

dp[i][0] = ∑ (1 ? ??[??]) ∏ ??[??] ?? ??+1 ???1 ??=0 ,dp[i][1]表示∑ (?? ? ?? ? ???1 ??=0 1)(1 ? ??[??]) ∏ ??[??] ?? ??+1 ,dp[i][2]

表 示 ∑ (i ? k ? 1) 2 (1 ? ??[??]) ∏ ??[??] ?? ??+1 ???1 ??=0 ,dp[i][3] 表 示 ∑ (i ? k ? 1) 3 (1 ? ??[??]) ∏ ??[??] ?? ??+1 ???1 ??=0

dp[i][0]=(dp[i-1][0]+1-a[i-1])*a[i];

dp[i][1]=(dp[i-1][0]+dp[i-1][1]+1-a[i-1])*a[i]

dp[i][2]=(dp[i-1][0]+2dp[i-1][1]+dp[i-1][2]+1-a[i-1])*a[i]

dp[i][3]=(dp[i-1][0]+3dp[i-1][1]+3dp[i-1][2]+dp[i-1][3]+1-a[i-1])*a[i]

ans=∑ ????[??][3] ? (1 ? ??[?? ? 1]) ?? ??=1

我们定义 a[0]=a[n+1]=0

Code

 1 #include<cstdio>
 2 using namespace std;
 3 double f,t2,t1,P;
 4 int N;
 5 int main()
 6 {
 7     freopen("osu.in","r",stdin),freopen("osu.out","w",stdout);
 8     scanf("%d",&N);
 9     for(int i=0;i<N;i++) {
10         scanf("%lf",&P);
11         f+=P*(3*(t2+t1)+1);
12         t2=P*(t2+2*t1+1);
13         t1=P*(t1+1);
14     }
15     printf("%.1f\n",f);
16 }

 

T3 显然是一道Dp题,那刚学的ac自动机练练手
f[i][j][s]表示构造到了第i位,j是ac自动机上的位置,s是目前完成的字串状态(二进制压缩)
枚举M集合里的元素,转移十分简单

Code

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define fo(i,a,b) for(int i=a;i<=b;i++)
 6 #define fd(i,a,b) for(int i=a;i>=b;i--)
 7 #define fh(i,x) for(int i=head[x];i;i=next[i])
 8 typedef long long LL;
 9 typedef double DB;
10 using namespace std;
11 inline int max(int x,int y){return (x<y)?y:x;}
12 inline int min(int x,int y){return (x<y)?x:y;}
13 inline int read() {
14     int x=0,f=1;char ch=getchar();
15     while(ch<0||ch>9)f=(ch==-)?-1:f,ch=getchar();
16     while(ch>=0&&ch<=9)x=x*10+(ch-0),ch=getchar();
17     return f*x;
18 }
19 const int maxn=100+50,mo=1e9+7;
20 int n,M,K,len,tot;
21 int f[maxn][maxn<<2][1<<8],d[3*maxn],a[35],cnt[35];
22 char s[35];
23 struct AC{int son[26],fail,bz;}tr[maxn<<2];
24 void add(int x,int i,int id) {
25     int num=s[i]-a;
26     if(!tr[x].son[num])tr[x].son[num]=++tot;
27     if(i!=len)add(tr[x].son[num],i+1,id);
28     else tr[tr[x].son[num]].bz=(1<<(id-1));
29 }
30 void make_fail() {
31     int l=0,r=1;
32     while(l<r) {
33         int x=d[++l];
34         fo(p,1,M) {
35             int t=a[p];
36             if(tr[x].son[t]) {
37                 int v=tr[x].son[t];
38                 if(!x)tr[v].fail=0;
39                 else tr[v].fail=tr[tr[x].fail].son[t];
40                 tr[v].bz|=tr[tr[v].fail].bz;
41                 d[++r]=v;
42             } else tr[x].son[t]=tr[tr[x].fail].son[t];
43         }
44     }
45 }
46 int main() {
47     n=read(),K=read();
48     fo(i,1,K)scanf("%s",s+1),len=strlen(s+1),add(0,1,i);
49     int x=read();
50     scanf("%s",s+1);
51     fo(i,1,x)if(!cnt[s[i]-a])cnt[s[i]-a]=1,a[++M]=s[i]-a;
52     make_fail();
53     f[0][0][0]=1;
54     fo(i,0,n-1)fo(j,0,tot)fo(k,0,(1<<K)-1)
55         if(f[i][j][k])fo(p,1,M) {
56             int next=tr[j].son[a[p]],finsh=k|tr[next].bz;
57             f[i+1][next][finsh]=(f[i+1][next][finsh]+f[i][j][k])%mo;
58         }
59     int ans=0;
60     fo(i,0,tot)ans=(ans+f[n][i][(1<<K)-1])%mo;
61     printf("%d\n",ans);
62     return 0;
63 }

 

以上是关于2017.11.25NOIP提高组模拟赛A组的主要内容,如果未能解决你的问题,请参考以下文章

2017.12.09NOIP提高组模拟赛A组

2017.12.02NOIP提高组模拟赛A组

NOIP提高组模拟赛13

P1065 [NOIP2006 提高组] 作业调度方案(模拟)

Jzoj4742NOIP2016提高A组模拟9.2快速幂单峰

NOIP2016提高A组模拟10.15总结