zoukankan      html  css  js  c++  java
  • NOIP模拟测试11

    这次考试T1想到了正解没有去实现,然后就死了,不过我估计就算想到正解也会挂(26^2和暴力一个分),肝了两个小时T2屁都没蹦出来,T3没有搞清那个式子的含义。

    (不过一分没挂)

    T1:string

    开26棵线段树维护,还有一种更快的方法:对于每个树上的节点,只有左右儿子字符相同时才更新,不然不更新,这种打法将26换成了较小的常数,并且不需要memset,真是出家旅行必备骗分之良器

     1 #include <bits/stdc++.h>
     2 
     3 typedef long long LL;
     4 
     5 inline int rd() {
     6     int a = 1, b = 0; char c = getchar();
     7     while (!isdigit(c)) a = c == '-' ? 0 : 1, c = getchar();
     8     while (isdigit(c)) b = b * 10 + c - '0', c = getchar();
     9     return a ? b : -b;
    10 }
    11 
    12 const int N = 100000 + 2333;
    13 
    14 int n, m; char str[N];
    15 
    16 int same[N * 3];
    17 
    18 #define ls(p) p << 1
    19 #define rs(p) p << 1 | 1
    20 
    21 void pushup(int p) {
    22     if (same[ls(p)] == same[rs(p)])
    23         same[p] = same[ls(p)];
    24     else same[p] = 0;
    25 }
    26 
    27 void pushdown(int p) {
    28     if (same[p])
    29         same[ls(p)] = same[rs(p)] = same[p];
    30 }
    31 
    32 void build(int p, int L, int R) {
    33     if (L == R) return (void)(same[p] = str[L]);
    34     int mid = (L + R) >> 1;
    35     build(ls(p), L, mid);
    36     build(rs(p), mid + 1, R);
    37     pushup(p);
    38 }
    39 
    40 void change(int p, int l, int r, int v, int L, int R) {
    41     if (l <= L && r >= R) return (void)(same[p] = v);
    42     pushdown(p); int mid = (L + R) >> 1;
    43     if (l <= mid) change(ls(p), l, r, v, L, mid);
    44     if (r > mid) change(rs(p), l, r, v, mid + 1, R);
    45     pushup(p);
    46 }
    47 
    48 int que[233];
    49 
    50 void query(int p, int l, int r, int L, int R) {
    51     if (l <= L && r >= R && same[p])
    52         return (void)(que[same[p]] += (R - L + 1));
    53     pushdown(p); int mid = (L + R) >> 1;
    54     if (l <= mid) query(ls(p), l, r, L, mid);
    55     if (r > mid) query(rs(p), l, r, mid + 1, R);
    56 }
    57 
    58 void write(int p, int L, int R) {
    59     if (L == R) return (void)(putchar(same[p]));
    60     pushdown(p); int mid = (L + R) >> 1;
    61     write(ls(p), L, mid);
    62     write(rs(p), mid + 1, R);
    63 }
    64 
    65 int main() {
    66     scanf("%d%d%s", &n, &m, str + 1);
    67     build(1, 1, n);
    68     while (m--) {
    69         int l, r, x; scanf("%d%d%d", &l, &r, &x);
    70         for (int i = 'a'; i <= 'z'; ++i) que[i] = 0;
    71         query(1, l, r, 1, n);
    72         if (x == 1) {
    73             for (int i = 'a', lst = l; i <= 'z'; ++i) if (que[i])
    74                 change(1, lst, lst + que[i] - 1, i, 1, n), lst = lst + que[i];
    75         } else {
    76             for (int i = 'z', lst = l; i >= 'a'; --i) if (que[i])
    77                 change(1, lst, lst + que[i] - 1, i, 1, n), lst = lst + que[i];
    78         }
    79     }
    80     write(1, 1, n);
    81     return 0;
    82 }
    Orz
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #define clr(x) memset(x,0,sizeof(x))
      5 using namespace std;
      6 const int MAXN=800100;
      7 int N,M;
      8 char s[MAXN];
      9 int t[30];
     10 char wd[MAXN*4];
     11 int cnt[MAXN*4][30],tg[MAXN];
     12 bool fg[MAXN*4];
     13 void bt(int p,int l,int r){
     14     tg[p]=-1;
     15     if(l==r){
     16         wd[p]=s[l];
     17         cnt[p][s[l]-'a']=1;
     18         return;
     19     }
     20     int mid=(l+r)>>1;
     21     bt(p<<1,l,mid);
     22     bt(p<<1|1,mid+1,r);
     23     int fgg=0;
     24     for(int i=0;i<26;++i){
     25         cnt[p][i]=cnt[p<<1][i]+cnt[p<<1|1][i];
     26         fgg+=(cnt[p][i]!=0);
     27     }
     28     fg[p]=(fgg==1);
     29 }
     30 void get(int p,int l,int r,int ll,int rr,int out[]){
     31     if(ll<=l && r<=rr){
     32         for(int i=0;i<26;++i)
     33             out[i]+=cnt[p][i];
     34         return;
     35     }
     36     if(tg[p]!=-1){
     37         int id=tg[p];
     38         int mid=(l+r)>>1;
     39         clr(cnt[p<<1]);
     40         clr(cnt[p<<1|1]);
     41         cnt[p<<1][id]=mid-l+1;
     42         cnt[p<<1|1][id]=r-(mid+1)+1;
     43         tg[p<<1]=tg[p<<1|1]=id;
     44         wd[p<<1]=wd[p<<1|1]=id+'a';
     45         fg[p<<1]=fg[p<<1|1]=1;
     46         tg[p]=-1;
     47     }
     48     int mid=(l+r)>>1;
     49     if(ll<=mid)
     50         get(p<<1,l,mid,ll,rr,out);
     51     if(rr>mid)
     52         get(p<<1|1,mid+1,r,ll,rr,out);
     53 }
     54 void cover(int p,int l,int r,int ll,int rr,int id){
     55     if(ll<=l && r<=rr){
     56         clr(cnt[p]);
     57         cnt[p][id]=r-l+1;
     58         tg[p]=id;
     59         wd[p]=id+'a';
     60         fg[p]=1;
     61         return;
     62     }
     63     if(tg[p]!=-1){
     64         int id=tg[p];
     65         int mid=(l+r)>>1;
     66         clr(cnt[p<<1]);
     67         clr(cnt[p<<1|1]);
     68         cnt[p<<1][id]=mid-l+1;
     69         cnt[p<<1|1][id]=r-(mid+1)+1;
     70         tg[p<<1]=tg[p<<1|1]=id;
     71         wd[p<<1]=wd[p<<1|1]=id+'a';
     72         fg[p<<1]=fg[p<<1|1]=1;
     73         tg[p]=-1;
     74     }
     75     int mid=(l+r)>>1;
     76     if(ll<=mid)
     77         cover(p<<1,l,mid,ll,rr,id);
     78     if(rr>mid)
     79         cover(p<<1|1,mid+1,r,ll,rr,id);
     80     int fgg=0;
     81     for(int i=0;i<26;++i){
     82         cnt[p][i]=cnt[p<<1][i]+cnt[p<<1|1][i];
     83         fgg+=(cnt[p]!=0);
     84     }
     85     fg[p]=(fgg==1);
     86 }
     87 void dfs(int p,int l,int r){
     88     if(l==r){
     89         printf("%c",wd[p]);
     90         return;
     91     }
     92     if(tg[p]!=-1){
     93         int id=tg[p];
     94         int mid=(l+r)>>1;
     95         clr(cnt[p<<1]);
     96         clr(cnt[p<<1|1]);
     97         cnt[p<<1][id]=mid-l+1;
     98         cnt[p<<1|1][id]=r-(mid+1)+1;
     99         tg[p<<1]=tg[p<<1|1]=id;
    100         wd[p<<1]=wd[p<<1|1]=id+'a';
    101         fg[p<<1]=fg[p<<1|1]=1;
    102         tg[p]=-1;
    103     }
    104     int mid=(l+r)>>1;
    105     dfs(p<<1,l,mid);
    106     dfs(p<<1|1,mid+1,r);
    107 }
    108 int main(){
    109     scanf("%d%d",&N,&M);
    110     char c=getchar();
    111     int len=0;
    112     while(c<'a' || c>'z')
    113         c=getchar();
    114     while(c<='z' && c>='a'){
    115         s[++len]=c;
    116         c=getchar();
    117     }
    118     bt(1,1,N);
    119     for(int i=1;i<=M;++i){
    120         int l,r,opt;
    121         scanf("%d%d%d",&l,&r,&opt);
    122         clr(t);
    123         get(1,1,N,l,r,t);
    124         if(opt==0){
    125             for(int i=25;i>=0;--i){
    126                 if(t[i])
    127                     cover(1,1,N,l,l+t[i]-1,i);
    128                 l+=t[i];
    129             }
    130         }
    131         else{
    132             for(int i=0;i<26;++i){
    133                 if(t[i])
    134                     cover(1,1,N,l,l+t[i]-1,i);
    135                 l+=t[i];
    136             }
    137         }
    138     }
    139     dfs(1,1,N);
    140 }
    正常AC代码
      1 #include<bits/stdc++.h>
      2 #define MAXN 100005
      3 #define cri const register int
      4 #define pt puts("----------------")
      5 using namespace std;
      6 int now[27];
      7 char s[MAXN];
      8 struct Seg_tree{
      9     int t[MAXN*4][27],f[MAXN*4];
     10     #define ls k<<1
     11     #define rs k<<1|1
     12     void change(cri k,cri l,cri r,cri gl,cri gr,cri val)
     13     {
     14         if(l>=gl&&r<=gr)
     15         {
     16             memset(t[k],0,sizeof(t[k]));
     17             t[k][val]=r-l+1;
     18             f[k]=val;
     19             return ;
     20         }
     21         register int mid=l+r>>1;
     22         if(f[k])
     23         {
     24             register int mid=l+r>>1;
     25             memset(t[ls],0,sizeof(t[ls]));
     26             memset(t[rs],0,sizeof(t[rs]));
     27             register int p=f[k];f[k]=0;
     28             t[ls][p]=mid-l+1;
     29             t[rs][p]=r-mid;
     30             f[ls]=f[rs]=p;
     31         }
     32         if(gl<=mid)change(ls,l,mid,gl,gr,val);
     33         if(gr>mid)change(rs,mid+1,r,gl,gr,val);
     34         t[k][1]=t[ls][1]+t[rs][1];
     35         t[k][2]=t[ls][2]+t[rs][2];
     36         t[k][3]=t[ls][3]+t[rs][3];
     37         t[k][4]=t[ls][4]+t[rs][4];
     38         t[k][5]=t[ls][5]+t[rs][5];
     39         t[k][6]=t[ls][6]+t[rs][6];
     40         t[k][7]=t[ls][7]+t[rs][7];
     41         t[k][8]=t[ls][8]+t[rs][8];
     42         t[k][9]=t[ls][9]+t[rs][9];
     43         t[k][10]=t[ls][10]+t[rs][10];
     44         t[k][11]=t[ls][11]+t[rs][11];
     45         t[k][12]=t[ls][12]+t[rs][12];
     46         t[k][13]=t[ls][13]+t[rs][13];
     47         t[k][14]=t[ls][14]+t[rs][14];
     48         t[k][15]=t[ls][15]+t[rs][15];
     49         t[k][16]=t[ls][16]+t[rs][16];
     50         t[k][17]=t[ls][17]+t[rs][17];
     51         t[k][18]=t[ls][18]+t[rs][18];
     52         t[k][19]=t[ls][19]+t[rs][19];
     53         t[k][20]=t[ls][20]+t[rs][20];
     54         t[k][21]=t[ls][21]+t[rs][21];
     55         t[k][22]=t[ls][22]+t[rs][22];
     56         t[k][23]=t[ls][23]+t[rs][23];
     57         t[k][24]=t[ls][24]+t[rs][24];
     58         t[k][25]=t[ls][25]+t[rs][25];
     59         t[k][26]=t[ls][26]+t[rs][26];
     60     }
     61     void query(cri k,cri l,cri r,cri gl,cri gr)
     62     {
     63         if(l>=gl&&r<=gr)
     64         {
     65             for(register int i=1;i<=26;i++)now[i]+=t[k][i];
     66             return ;
     67         }
     68         register int mid=l+r>>1;
     69         if(f[k])
     70         {
     71             register int mid=l+r>>1;
     72             memset(t[ls],0,sizeof(t[ls]));
     73             memset(t[rs],0,sizeof(t[rs]));
     74             register int p=f[k];f[k]=0;
     75             t[ls][p]=mid-l+1;
     76             t[rs][p]=r-mid;
     77             f[ls]=f[rs]=p;
     78         }
     79         if(gl<=mid)query(ls,l,mid,gl,gr);
     80         if(gr>mid)query(rs,mid+1,r,gl,gr);
     81         return ;
     82     }
     83     void Build(cri k,cri l,cri r)
     84     {
     85         if(l==r)
     86         {
     87             t[k][s[l-1]-'a'+1]=1;
     88             return ;
     89         }
     90         register int mid=l+r>>1;
     91         Build(ls,l,mid);
     92         Build(rs,mid+1,r);
     93         t[k][1]=t[ls][1]+t[rs][1];
     94         t[k][2]=t[ls][2]+t[rs][2];
     95         t[k][3]=t[ls][3]+t[rs][3];
     96         t[k][4]=t[ls][4]+t[rs][4];
     97         t[k][5]=t[ls][5]+t[rs][5];
     98         t[k][6]=t[ls][6]+t[rs][6];
     99         t[k][7]=t[ls][7]+t[rs][7];
    100         t[k][8]=t[ls][8]+t[rs][8];
    101         t[k][9]=t[ls][9]+t[rs][9];
    102         t[k][10]=t[ls][10]+t[rs][10];
    103         t[k][11]=t[ls][11]+t[rs][11];
    104         t[k][12]=t[ls][12]+t[rs][12];
    105         t[k][13]=t[ls][13]+t[rs][13];
    106         t[k][14]=t[ls][14]+t[rs][14];
    107         t[k][15]=t[ls][15]+t[rs][15];
    108         t[k][16]=t[ls][16]+t[rs][16];
    109         t[k][17]=t[ls][17]+t[rs][17];
    110         t[k][18]=t[ls][18]+t[rs][18];
    111         t[k][19]=t[ls][19]+t[rs][19];
    112         t[k][20]=t[ls][20]+t[rs][20];
    113         t[k][21]=t[ls][21]+t[rs][21];
    114         t[k][22]=t[ls][22]+t[rs][22];
    115         t[k][23]=t[ls][23]+t[rs][23];
    116         t[k][24]=t[ls][24]+t[rs][24];
    117         t[k][25]=t[ls][25]+t[rs][25];
    118         t[k][26]=t[ls][26]+t[rs][26];
    119     }
    120 }T;
    121 inline int Rd()
    122 {
    123     register int x=0,f=1;register char c=getchar();
    124     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    125     while(c>='0'&&c<='9'){x=x*10+c-48;c=getchar();}
    126     return x*f;
    127 }
    128 int n,m;
    129 int main()
    130 {
    131     scanf("%d%d%s",&n,&m,s);
    132     T.Build(1,1,n);
    133     while(m--)
    134     {
    135         memset(now,0,sizeof(now));
    136         register int l,r,x,t,k;
    137         l=Rd();r=Rd();x=Rd();
    138         k=l;
    139         T.query(1,1,n,l,r);
    140         if(x)
    141         {
    142             t=1;
    143             while(t<=26)
    144             {
    145                 while(!now[t]&&t<=26)++t;
    146                 T.change(1,1,n,k,k+now[t]-1,t);
    147                 k+=now[t];
    148                 now[t]=0;
    149             }
    150         }
    151         else 
    152         {
    153             t=26;
    154             while(t>=0)
    155             {
    156                 while(!now[t]&&t>=0)--t;
    157                 T.change(1,1,n,k,k+now[t]-1,t);
    158                 k+=now[t];
    159                 now[t]=0;
    160             }
    161         }
    162     }
    163     for(int i=1;i<=n;i++)
    164     {
    165         memset(now,0,sizeof(now));
    166         T.query(1,1,n,i,i);
    167         for(int j=1;j<=26;j++)
    168             if(now[j])
    169             {
    170                 putchar('a'+j-1);
    171                 break;
    172             }
    173     }
    174     puts("");
    175     return 0;
    176 }
    我的AC代码。
     1 #include<cstdio>
     2 char s[100005],bucx[100005];int bucr[100005],buc[127],n,m;
     3 main(){
     4     scanf("%d%d%s",&n,&m,s+1);bucr[n+1]=n+1;
     5     for(int i=1;i<=n;++i)bucr[i]=i,bucx[i]=s[i];
     6     for(int i=1,l,r,x;i<=m;++i){
     7         scanf("%d%d%d",&l,&r,&x);
     8         int j;for(j=l;!bucr[j];--j);
     9         int k=bucr[j]+1;if(j!=l)buc[bucx[j]]+=bucr[j]-l+1,bucr[j]=l-1;else k=j;
    10         while(bucr[k]<=r){
    11             buc[bucx[k]]+=bucr[k]-k+1;
    12             int lst=k;k=bucr[k]+1;bucr[lst]=0;
    13         }
    14         if(k<=r)buc[bucx[k]]+=r-k+1,bucr[r+1]=bucr[k],bucx[r+1]=bucx[k],bucr[k]=0;
    15         if(x)for(char ch='a';ch<='z';++ch)if(buc[ch])bucr[l]=l+buc[ch]-1,bucx[l]=ch,l=bucr[l]+1,buc[ch]=0;
    16         if(!x)for(char ch='z';ch>='a';--ch)if(buc[ch])bucr[l]=l+buc[ch]-1,bucx[l]=ch,l=bucr[l]+1,buc[ch]=0;
    17     }
    18     for(int i=1;i<=n;i=bucr[i]+1)for(int j=i;j<=bucr[i];++j)putchar(bucx[i]);
    19 }
    300ms做法

    Orz wd暴力QJ神仙打法

    T2:matrix

    dp状态设的很神 f[i][j]表示前i列满足j个有区间且满足题意的方案数

    先设ls[i]表示右端点在前i列的左区间的方案数,rs[i]表示左端点在前i列的右区间的方案数

    然后就可以转移了,考虑列数增还是不增

    不增:f[i+1][j]+=f[i][j]

    增:f[i+1][j+1]+=f[i][j]*(rs[i+1]-j)

    注意左侧区间我们并没有考虑,实际考虑,供我们选的列有i-j个,前一个状态已经选了ls[i-1]个,新增状态有ls[i]-ls[i-1]个。

    用新增状态塞满可选状态并要考虑顺序,同时还有一个合法状态的判定然后就没啦

    说起来很简单,但状态真的难想,但也不无道理。

    这个题紧紧扣住列,而与具体是哪行无关,所以i,j都与列有关,同时为了方便转移,我们抓住一侧的区间,状态及其转移就显然了。

    还是要抓住题目核心性质。

     1 #include<bits/stdc++.h>
     2 #define MAXN 3005
     3 #define int long long
     4 using namespace std;
     5 const int mod=998244353;
     6 int f[MAXN][MAXN],ls[MAXN],rs[MAXN],l[MAXN],r[MAXN],A[MAXN][MAXN];
     7 signed main()
     8 {
     9     int n,m;
    10     scanf("%lld%lld",&n,&m);
    11     for(int i=1;i<=n;i++)
    12     {
    13         scanf("%lld%lld",&l[i],&r[i]);
    14         ls[l[i]]++;rs[r[i]]++;
    15     }
    16     for(int i=1;i<=m;i++)ls[i]+=ls[i-1],rs[i]+=rs[i-1];
    17     A[0][0]=A[0][1]=1;f[0][0]=1;
    18     for(int i=1;i<=m;i++)
    19     {
    20         A[i][0]=1;A[i][1]=i;
    21         for(int j=2;j<=i;j++)
    22             A[i][j]=A[i][j-1]*(i-j+1)%mod;
    23     }
    24     for(int i=0;i<=m;i++)
    25     {
    26         for(int j=0;j<=min(i,n);j++)
    27         {
    28             if(i-j<ls[i])break;
    29             (f[i][j]*=A[i-j-ls[i-1]][ls[i]-ls[i-1]])%=mod;
    30             (f[i+1][j]+=f[i][j])%=mod;
    31             (f[i+1][j+1]+=f[i][j]*max(0ll,rs[i+1]-j))%=mod;
    32         }
    33     }
    34     cout<<f[m][n]<<endl;
    35     return 0;
    36 }
    View Code

     

    T3:big

    这题的难点在于如何转化题意

    这个式子实际上就是x的逻辑左移,然后后面就显然了,开一颗Trie树,求最大值即可

     1 #include<bits/stdc++.h>
     2 #define re register
     3 using namespace std;
     4 const int MAXN=100000;
     5 int n,maxx,val,sum[MAXN],psum[MAXN],num;
     6     int ch[MAXN*50][2],tot;
     7     void insert(const int x)
     8     {
     9         re int p=0;
    10         for(int i=n-1;i>=0;i--)
    11         {
    12             re int k=(x>>i)&1;
    13             if(!ch[p][k])ch[p][k]=++tot;
    14             p=ch[p][k];
    15         }
    16         return ;
    17     }
    18     void Getans(const int x,int val,int dep)
    19     {
    20         if(!ch[x][0]&&!ch[x][1])
    21         {
    22             if(val==maxx)num++;
    23             else if(val>maxx)maxx=val,num=1;
    24             return ;
    25         }
    26         if(ch[x][0]&&ch[x][1]){
    27             Getans(ch[x][0],val,dep+1);
    28             Getans(ch[x][1],val,dep+1);
    29             return ;
    30         }
    31         if(!ch[x][0]||!ch[x][1]){
    32             Getans(ch[x][0]|ch[x][1],val+(1<<(n-dep-1)),dep+1);
    33         }
    34         return ;
    35     }
    36 int main()
    37 {
    38     int m;
    39     scanf("%d%d",&n,&m);
    40     for(int i=1;i<=m;i++)
    41     {
    42         register int a,k=0;scanf("%d",&a);
    43         sum[i]=sum[i-1]^a;
    44         if((a>>(n-1))&1)k=1;
    45         (k+=a<<1)&=((1<<n)-1);
    46         psum[i]=psum[i-1]^k;
    47     }
    48     for(int i=0;i<=m;i++)
    49         insert(psum[i]^(sum[m]^sum[i]));
    50     Getans(0,0,0);
    51     cout<<maxx<<endl<<num<<endl;
    52     return 0;
    53 }
    View Code

    总结:

    1.分析题目核心性质

    2.转化题意

    3.卡常

     

  • 相关阅读:
    hdu 1269 迷宫城堡 (并查集)
    hdu 1272 小希的迷宫 (深搜)
    hdu 1026 Ignatius and the Princess I (深搜)
    hdu 1099 Lottery
    hdu 1068 Girls and Boys (二分匹配)
    几个基础数位DP(hdu 2089,hdu 3555,uestc 1307 windy 数)
    hdu 1072 Nightmare (广搜)
    hdu 1398 Square Coins (母函数)
    hdu 1253 胜利大逃亡 (深搜)
    hdu 1115 Lifting the Stone (求重心)
  • 原文地址:https://www.cnblogs.com/hzoi-kx/p/11286735.html
Copyright © 2011-2022 走看看