• [bzoj4722] 由乃


    题意:两种操作。1、将所给区间划分成两个集合,集合中的元素的贡献为a[i]+1,求是否能找出两个集合使两个集合的总贡献相等。2、区间立方(有模数)

    题解:

    倍增+线段树+搜索(meet in the middle)

    区间立方:由于模数比较小,我们可以用倍增预处理某个数的2^j次立方,然后用线段树维护查询的次数,单次复杂度:O(logn)

    划分集合:

    首先有个结论,由于所有数的最大范围只有1000,所以超过13个数一定能通过加减等于0

    对于范围小于等于13的区间,首先查出每个数操作后得到的数,然后用meet in the middle暴搜出解,单次复杂度:O(logn+3^7)

    总复杂大概是:O(m*(logn+3^7))

    然后这题我犯了一大堆傻逼错误,调了一个下午,我也是醉了

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<cmath>
      7 #define ll long long
      8 #define ls x<<1
      9 #define rs x<<1|1
     10 #define N 100010
     11 #define M 15000
     12 using namespace std;
     13 
     14 int n,m,v,top;
     15 int a[N],tr[N*4],lazy[N*4],f[1010][22],st[N],val[20];
     16 bool flg,vis[N];
     17 
     18 int gi() {
     19   int x=0,o=1; char ch=getchar();
     20   while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
     21   if(ch=='-') o=-1,ch=getchar();
     22   while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
     23   return o*x;
     24 }
     25 
     26 void pre() {
     27   for(int i=0; i<v; i++) f[i][0]=i*i*i%v;//错点1:初始化对象错误
     28   for(int j=1; j<=20; j++)
     29     for(int i=0; i<v; i++)
     30       f[i][j]=f[f[i][j-1]][j-1];
     31 }
     32 
     33 void pushdown(int x) {
     34   if(!lazy[x]) return;
     35   tr[ls]+=lazy[x],tr[rs]+=lazy[x];
     36   lazy[ls]+=lazy[x],lazy[rs]+=lazy[x];
     37   lazy[x]=0;
     38 }
     39 
     40 void update(int x, int l, int r, int ql, int qr) {
     41   if(ql<=l && r<=qr) {
     42     tr[x]++,lazy[x]++;//其实只要开一个就够了,反正每次只会查询叶子= =、
     43     return;
     44   }
     45   pushdown(x);
     46   int mid=(l+r)>>1;
     47   if(qr<=mid) update(ls,l,mid,ql,qr);
     48   else if(ql>mid) update(rs,mid+1,r,ql,qr);
     49   else update(ls,l,mid,ql,mid),update(rs,mid+1,r,mid+1,qr);
     50 }
     51 
     52 int query(int x, int l, int r, int qx) {
     53   if(l==r) return tr[x];
     54   pushdown(x);//错点3:查询时没有pushdown
     55   int mid=(l+r)>>1;
     56   if(qx<=mid) return query(ls,l,mid,qx);
     57   else return query(rs,mid+1,r,qx);
     58 }
     59 
     60 int get(int x) {
     61   int y=query(1,1,n,x),ret=a[x];
     62   for(int i=20; i>=0; i--) {
     63     if(y&(1<<i)) ret=f[ret][i];
     64   }
     65   return ret;
     66 }
     67 
     68 void dfs1(int dep, int k, int sum, int siz) {
     69   if(dep>k) {
     70     vis[sum+M]=1,st[++top]=sum;
     71     if(!sum && siz) flg=1;
     72     return;
     73   }
     74   dfs1(dep+1,k,sum,siz);
     75   if(flg) return;
     76   dfs1(dep+1,k,sum+val[dep]+1,siz+1);
     77   if(flg) return;
     78   dfs1(dep+1,k,sum-val[dep]-1,siz+1);
     79 }
     80 
     81 void dfs2(int dep, int k, int sum, int siz) {
     82   if(dep>k) {
     83     if((vis[-sum+M] && sum!=0) || (!sum && siz)) flg=1;
     84     return;
     85   }
     86   dfs2(dep+1,k,sum,siz);
     87   if(flg) return;//错点5:没打分号
     88   dfs2(dep+1,k,sum+val[dep]+1,siz+1);
     89   if(flg) return;
     90   dfs2(dep+1,k,sum-val[dep]-1,siz+1);
     91 }
     92 
     93 bool check(int x) {
     94   for(int i=1; i<=top; i++) vis[st[i]+M]=0;
     95   top=0,flg=0;
     96   dfs1(1,x/2,0,0);
     97   if(flg) return true;
     98   dfs2(x/2+1,x,0,0);
     99   if(flg) return true;
    100   return false;//错点4:返回false时没有清空数组
    101 }
    102 
    103 int main() {
    104   n=gi(),m=gi(),v=gi();
    105   for(int i=1; i<=n; i++) a[i]=gi();
    106   pre();
    107   for(int i=1; i<=m; i++) {
    108     int op=gi(),l=gi(),r=gi();
    109     if(op==2) update(1,1,n,l,r); 
    110     else {
    111       if(r-l+1>13) puts("Yuno");
    112       else {
    113       for(int j=l; j<=r; j++) val[j-l+1]=get(j);//错点2:重复用i循环
    114       if(check(r-l+1)) puts("Yuno");
    115       else puts("Yuki");
    116       }
    117     }
    118   }
    119   return 0;
    120 }
  • 相关阅读:
    【梅西加油!】梅西加油!!加油梅西!!
    [CQOI2014][bzoj3507] 通配符匹配 [字符串hash+dp]
    [NOI2011][bzoj2434] 阿狸的打字机 [AC自动机+dfs序+fail树+树状数组]
    [USACO12Jan][luogu3041] Video Game Combos [AC自动机+dp]
    [HNOI2004][bzoj1212] L语言 [Trie+dp]
    [POI2005][luogu3462] SZA-Template [fail树]
    [HNOI2008][bzoj1009] GT考试 [KMP+矩阵快速幂]
    [SDOI2008][luogu2463] Sandy的卡片 [kmp]
    [POI2006][luogu3435] OKR-Periods of Words [kmp+next数组]
    [NOI2014][bzoj3670] 动物园 [kmp+next数组应用]
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7608119.html
Copyright © 2020-2023  润新知