zoukankan      html  css  js  c++  java
  • bzoj4722 由乃

    Description

    由于一周目的由乃穿越到了三周目,并带来了巨大的影响,改变了三周目所有未来日记所有者的命运所以三周目的神Deus准备不利用未来日记来决定把神的位置交给谁Deus特别崇拜某知名社会主义国家领导人,因为他的寿命比神还长,所以他想钦定下一个卡密,而不通过选举他决定钦定三周目的由乃成为卡密,去和一周目的雪辉重逢(终于做了一件好事了)但是,既然是钦定,那么肯定还是要做做样子的,以防某些来自香港的记者造个大新闻,导致被批判一番所以Deus决定,出一道OI题来考察由乃有没有当神的能力如果你没有看过这个番,以上内容可以无视
    给一个长为n的序列a,每个数在0到v - 1之间,有m次操作。
    操作1:每次询问一个区间中是否可以选出两个下标的集合X,Y,满足:
    1.X和Y没有交集
    2.设集合X中有一个元素是i,则其对集合X的贡献是a[i] + 1,要求集合X的元素的总贡献和集合Y的元素的总贡献
    相等如果可以选出这两个集合,输出 Yuno否则输出 Yuki
    操作2:修改一个区间l,r之间的数,使得所有l <= i <= r,a[i] = a[i] * a[i] * a[i] % v ,即区间立方
    如果你没有看过这个番,或者你已经是国家队队员,以下内容可以无视
    可以去和雪辉重逢,由乃肯定非常高兴然而可爱的由乃虽然很机智但是并不会OI呀,特别不会数据结构这种神奇的东西(会数据结构和成为卡密有什么关系吗233333)所以她请您——未来的国家队队员来帮助她啦

    Input

    第一行三个数n , m , v,意义如题所述
    之后一行n个数,表示序列a
    之后m行每行三个数opt , l , r,表示操作类型是1还是2,操作的区间是[l , r] 

    Output

    m行,每行一个字符串 Yuno 或者 Yuki 表示能否选出这两个集合 

    Sample Input

    20 20 152
    3 26 133 54 79 81 72 109 66 91 82 100 35 23 104 17 51 114 12 58
    2 1 17
    2 6 12
    1 1 12
    2 3 5
    2 11 11
    2 7 19
    2 6 15
    1 5 12
    1 1 9
    1 10 19
    2 3 19
    2 6 20
    2 1 13
    2 1 15
    2 1 9
    1 1 1
    2 1 7
    2 7 19
    2 6 19
    2 3 6

    Sample Output

    Yuno
    Yuno
    Yuno
    Yuno
    Yuki

    HINT 

    总算在bzoj上出题了呀
    这下可以安心退役了~
    总共有10组数据
    对于100%的数据,n , m <= 100000 , v <= 1000,数据没有梯度

    正解:线段树+倍增+搜索。

    首先这题有一个神奇的性质,就是当询问区间长度大于$13$的时候一定有合法解,因为$2^{14}>14*1000$。

    然后我们判断一下,如果区间长度$leq13$,那么我们就可以写$meet in the middle$,做到单次询问$O(3^{7})$。

    再看修改怎么搞,因为$v<1000$,所以我们可以存下$x$的三次方是什么,进一步,可以存下$x$的$2^{k}$次三次方是什么,那么我们直接写一个倍增就行了。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define ls (x<<1)
     6 #define rs (x<<1|1)
     7 #define N (300010)
     8 #define M (50010)
     9 
    10 using namespace std;
    11 
    12 int fa[21][N],sum[N<<2],tag[N<<2],vis[N],st[N],f[N],n,m,v,fg,top;
    13 
    14 il int gi(){
    15   RG int x=0,q=1; RG char ch=getchar();
    16   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    17   if (ch=='-') q=-1,ch=getchar();
    18   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    19   return q*x;
    20 }
    21 
    22 il void pushdown(RG int x){
    23   tag[ls]+=tag[x],tag[rs]+=tag[x],tag[x]=0; return;
    24 }
    25 
    26 il void build(RG int x,RG int l,RG int r){
    27   if (l==r){ sum[x]=gi(); return; } RG int mid=(l+r)>>1;
    28   build(ls,l,mid),build(rs,mid+1,r); return;
    29 }
    30 
    31 il void update(RG int x,RG int l,RG int r,RG int xl,RG int xr){
    32   if (xl<=l && r<=xr){ ++tag[x]; return; }
    33   if (tag[x]) pushdown(x); RG int mid=(l+r)>>1;
    34   if (xr<=mid) update(ls,l,mid,xl,xr);
    35   else if (xl>mid) update(rs,mid+1,r,xl,xr);
    36   else update(ls,l,mid,xl,mid),update(rs,mid+1,r,mid+1,xr);
    37   return;
    38 }
    39 
    40 il int query(RG int x){
    41   sum[x]%=v;
    42   for (RG int j=20;j>=0;--j)
    43     if (tag[x]>=(1<<j)) tag[x]-=1<<j,sum[x]=fa[j][sum[x]];
    44   return sum[x];
    45 }
    46 
    47 il void find(RG int x,RG int l,RG int r,RG int xl,RG int xr,RG int p){
    48   if (l==r){ f[r-p+1]=query(x); return; }
    49   if (tag[x]) pushdown(x); RG int mid=(l+r)>>1;
    50   if (xr<=mid) find(ls,l,mid,xl,xr,p);
    51   else if (xl>mid) find(rs,mid+1,r,xl,xr,p);
    52   else find(ls,l,mid,xl,mid,p),find(rs,mid+1,r,mid+1,xr,p);
    53 }
    54 
    55 il void dfs1(RG int x,RG int lim,RG int sz,RG int tot){
    56   if (x>lim){
    57     if (!sz) return; if (!tot){ fg=1; return; }
    58     vis[tot+M]=1,st[++top]=tot; return;
    59   }
    60   dfs1(x+1,lim,sz+1,tot-f[x]-1),dfs1(x+1,lim,sz,tot);
    61   dfs1(x+1,lim,sz+1,tot+f[x]+1); return;
    62 }
    63 
    64 il void dfs2(RG int x,RG int lim,RG int sz,RG int tot){
    65   if (x>lim){
    66     if (!sz) return; if (!tot) fg=1;
    67     if (vis[M-tot]) fg=1; return;
    68   }
    69   dfs2(x+1,lim,sz+1,tot-f[x]-1),dfs2(x+1,lim,sz,tot);
    70   dfs2(x+1,lim,sz+1,tot+f[x]+1); return;
    71 }
    72 
    73 il int check(RG int len){
    74   if (len>13) return 1; fg=top=0,dfs1(1,len/2,0,0);
    75   if (fg){ for (RG int i=1;i<=top;++i) vis[st[i]+M]=0; return 1; }
    76   dfs2(len/2+1,len,0,0); for (RG int i=1;i<=top;++i) vis[st[i]+M]=0; return fg;
    77 }
    78 
    79 int main(){
    80 #ifndef ONLINE_JUDGE
    81   freopen("yuno.in","r",stdin);
    82   freopen("yuno.out","w",stdout);
    83 #endif
    84   n=gi(),m=gi(),v=gi(),build(1,1,n);
    85   for (RG int i=1;i<v;++i) fa[0][i]=1LL*i*i*i%v;
    86   for (RG int j=1;j<=20;++j)
    87     for (RG int i=1;i<v;++i) fa[j][i]=fa[j-1][fa[j-1][i]];
    88   while (m--){
    89     RG int op=gi(),l=gi(),r=gi();
    90     if (op==1){
    91       if (r-l+1<=13) find(1,1,n,l,r,l);
    92       puts(check(r-l+1) ? "Yuno" : "Yuki");
    93     } else update(1,1,n,l,r);
    94   }
    95   return 0;
    96 }
  • 相关阅读:
    CSS处理小技巧
    React 脚手架构建
    Tomcat8学习
    javaScript(ES5中的类,原型,原型对象和函数对象的关系)
    保留两位小数(逢5进位,精度不会丢失)
    获取过去12个月
    mybatis 踩坑记录
    动态代理--jdk和cglib
    lambda表达式
    mybatis的mapper映射配置文件详解
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7603563.html
Copyright © 2011-2022 走看看