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.卡常

     

  • 相关阅读:
    [LeetCode]113. Maximum Depth of Binary Tree二叉树的最大深度
    [LeetCode]112. Maximum Subarray最大和连续子序列
    [LeetCode]111. Find Minimum in Rotated Sorted Array II旋转数组最小值II
    [LeetCode]110. Find Minimum in Rotated Sorted Array旋转数组最小值
    [LeetCode]109. Construct Binary Tree from Inorder and Postorder Traversal由中序序列和后序序列重建二叉树
    [LeetCode]108. Construct Binary Tree from Preorder and Inorder Traversal由前序序列和中序序列重建二叉树
    [LeetCode]107. Best Time to Buy and Sell Stock III股票买卖III
    [LeetCode]106. Best Time to Buy and Sell Stock II股票买卖II
    [LeetCode]105. Word Search单词查找
    一些杂事之后,该收心了
  • 原文地址:https://www.cnblogs.com/hzoi-kx/p/11286735.html
Copyright © 2011-2022 走看看