BZOJ:4333: JSOI2012 智者的考验

4333: JSOI2012 智者的考验

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 68  Solved: 18
[Submit][Status][Discuss]

Description

公元1371年,太祖下令在北极阁上大建庙宇,短短几年,鸡笼山上便建成了帝王庙、关公庙、真武庙、功臣庙、蒋王庙、都城隍庙、卞壶庙、忠烈庙、刘越王庙、曹武惠王庙共十座庙宇,统称为“十庙”。

后来,为了方便人们来鸡笼山进香礼佛,太祖下令疏通了鸡笼山下已淤塞多年的潮沟。于是,便有了“进香河”。

然而并不是所有人都可以来鸡笼山的,太祖在进香河上修建了一座石桥,中间悬挂了一块高Rx宽Ry的机关格图(如下图所示)。所有格子都是活动可翻转的,一面是白色,一面是黑色,这里我们用0表示白色,用1表示黑色。初始情况下,所有格子都是白色面朝前的。有Rx+Ry个机关按钮,对应Rx行和Ry列。一个按钮一旦触发,就会引发对应的一行或一列的格子同时翻转。

同时,善于识天象的谋臣刘基给出了一种黑白状态,称之为“厄运星”。每一位过往前去鸡笼山的人都需要触发且只触发一个按钮,触发后,如果来访者呈“厄运星”形状,则不允许通过。

每一天要来鸡笼山的人数N是事先就知道的,同时天朝神威浩荡,每一位来者一开始总是有很大概率触发编号为1的按钮,我们不妨用数列A1,A2,…,AN来表示,问题保证了初始时候的A数列全为1。同时在整个问题中,Ai满足1<=Ai<=Rx+Ry。太祖很关心那些不允许去鸡笼山的人数。于是他时不时就会询问关于“某一段时间内会有多少人不能通过“厄运星”的考验”。然而那些前来鸡笼山的文人墨客并不愿意如此单一的操作。来访者有可能会突然决定修改自己的触发按钮。更麻烦的情况,结伴而来的连续若干人会突然决定修改触发按钮并且都去触发同一个按钮。

现在这麻烦的问题交给了你。

后记:

等到了乾隆时期,一位人称纪昀的才子来访此地,告诉了人们一套方法,从此再也没有人会不被允许通过了。久而久之,鸡笼山烟火依旧,然这机关格图的故事便渐渐失传了。直到今天才再一次被世人所了解。

Input

输入文件第一行有2个数字Rx和Ry表示机关格图的高和宽(如图所示)。之后Rx行每一行Ry个数字,描述了“厄运星”形状,每一个数字都满足非0即1.

之后一行有两个数字,分别为N和M,表示人数和询问修改的次数。

之后M行,对应M次询问或修改。每一行先有一个数字t:

若t为0:之后有2个数字d和x,表明将Ad修改为x。

若t为1:之后有2个数字l和r,表明询问第l个人到第r个人中有多少人触发按钮后会出现“厄运星”形状,从而无法通过。

若t为2:之后有3个数字l,r和x,表面将Al,Al+1,…,Ar-1,Ar都修改为x。

Output

对于每一次询问(即t为1的情况),输出单独一行,一个整数描述了在区间[l,r]中满足要求的人数。

Sample Input

2 3

0 0 1

1 1 0

7 4

1 1 7

0 2 3

0 3 4

1 1 7

Sample Output

0

3

(有时候还是觉得复制一下题面挺好的

问题显然可以转化成带修地查询区间内前缀异或和为给定数的数量。

嗯?好像有64种状态?

不对不对,5个按钮应该是2^5=32种状态?

哦,把所有按钮都取反跟原来是一样,那就是2^4=16种状态。

那就可做了!

区间修改为某个数的影响最多只有1次(两两抵消)。

线段树上打打标记就可以了(我怎么还写了一早上啊)

#include<cstdio>
#include<cstring>
#include<algorithm>
#define MN 1000001
using namespace std;

int read_p,read_ca;
inline int read(){
    read_p=0;read_ca=getchar();
    while(read_ca<‘0‘||read_ca>‘9‘) read_ca=getchar();
    while(read_ca>=‘0‘&&read_ca<=‘9‘) read_p=read_p*10+read_ca-48,read_ca=getchar();
    return read_p;
}
struct na{int c[16],sum,l,r,y,a,Q,V;}t[MN<<1];
int n,m,q,rx,ry,o[10],s[16],to[16][10],num=0,bo,ro=0,x,N[64];
void build(int &p,int l,int r){
    if (p==0) p=++num,t[p].l=t[p].r=t[p].sum=t[p].y=0,t[p].a=-1;
    t[p].c[N[0]]=((r-l)>>1)+(!(l&1)||!(r&1));
    t[p].c[N[o[0]]]=((r-l)>>1)+((l&1)||(r&1));t[p].sum=((((r-l)>>1)+((l&1)||(r&1)))&1)*o[0];
    if (l==r) return;
    int mid=l+r>>1;
    build(t[p].l,l,mid);build(t[p].r,mid+1,r);
}
void pd(int p,int l,int r){
    if (t[p].a!=-1){
        if (t[p].l) t[t[p].l].a=t[p].a,t[t[p].l].V=t[p].V,t[t[p].l].Q=t[p].Q,t[t[p].l].y=0;
        if (t[p].r) t[t[p].r].a=t[p].a,t[t[p].r].V=t[p].V,t[t[p].r].Q=t[p].Q,t[t[p].r].y=0;
        memset(t[p].c,0,sizeof(t[p].c));
        t[p].c[N[t[p].V]]=((r-l)>>1)+(!(l-t[p].Q&1)||!(r-t[p].Q&1));
        t[p].c[N[t[p].a^t[p].V]]=((r-l)>>1)+((l-t[p].Q&1)||(r-t[p].Q&1));t[p].sum=((((r-l)>>1)+((l-t[p].Q&1)||(r-t[p].Q&1)))&1)*t[p].a^((r-l+1&1)*t[p].V);
        t[p].a=-1;
    }
}
void up(int p,int l,int r){
    int mid=l+r>>1;
    pd(t[p].l,l,mid);pd(t[p].r,mid+1,r);
    t[p].sum=t[t[p].l].sum^t[t[p].r].sum^(((mid-l+1)&1)*t[t[p].l].y)^(((r-mid)&1)*t[t[p].r].y);
    for (int i=0;i<16;i++) t[p].c[i]=t[t[p].l].c[N[s[i]^t[t[p].l].y]]+t[t[p].r].c[N[s[i]^t[t[p].r].y]];
}
void cg(int p,int l,int r,int po,int v){
    if (po<=l) t[p].y^=v;else{
        pd(p,l,r);
        int mid=l+r>>1;
        cg(t[p].r,mid+1,r,po,v);
        if (mid>=po) cg(t[p].l,l,mid,po,v);
        up(p,l,r);
    }
}
int ask(int p,int l,int r,int po){
    if (t[p].a!=-1) return (t[p].a*(po-t[p].Q&1))^t[p].V^t[p].y;
    if (l==r) return t[p].sum^t[p].y;
    int mid=l+r>>1;
    if (po<=mid) return ask(t[p].l,l,mid,po)^t[p].y;else return ask(t[p].r,mid+1,r,po)^t[p].y;
}
int que(int p,int l,int r,int L,int R,int v){
    pd(p,l,r);
    v^=t[p].y;
    if (L==l&&R==r) return t[p].c[N[v]];
    int mid=l+r>>1;
    if (R<=mid) return que(t[p].l,l,mid,L,R,v);else
    if (L>mid) return que(t[p].r,mid+1,r,L,R,v);else
    return que(t[p].l,l,mid,L,mid,v)+que(t[p].r,mid+1,r,mid+1,R,v);
}
void ca(int p,int l,int r,int L,int R,int v,int V,int Q){
    if (L==l&&R==r){
        t[p].a=v;t[p].V=V;t[p].y=0;t[p].Q=Q;
        t[p].c[N[V]]=((r-l)>>1)+(!(l-Q&1)||!(r-Q&1));
        t[p].c[N[v^V]]=((r-l)>>1)+((l-Q&1)||(r-Q&1));t[p].sum=(((((r-l)>>1)+((l-Q&1)||(r-Q&1)))&1)*v)^((r-l+1&1)*V);
    }else{
        pd(p,l,r);V^=t[p].y;
        int mid=l+r>>1;
        if (R<=mid) ca(t[p].l,l,mid,L,R,v,V,Q);else
        if (L>mid) ca(t[p].r,mid+1,r,L,R,v,V,Q);else
        ca(t[p].l,l,mid,L,mid,v,V,Q),ca(t[p].r,mid+1,r,mid+1,R,v,V,Q);
        up(p,l,r);
    }
}
int main(){
    register int i,j;
    rx=read();ry=read();n=0;
    for (i=0;i<rx;i++)
    for (j=0;j<ry;j++) o[i]^=1<<(i*ry+j),o[j+rx]^=1<<(i*ry+j),q^=read()<<(i*ry+j);
    n=read();m=read();
    s[bo=num=0]=0;
    for(;bo<=num;){
        for (i=0;i<rx+ry;i++){
            for (j=0;j<=num;j++)
            if (s[j]==(s[bo]^o[i])) break;
            if (j>num) s[++num]=s[bo]^o[i];
            to[bo][i]=j;
        }
        bo++;
    }
    for (i=0;i<64;i++) N[i]=-1;
    for (i=0;i<=num;i++) N[s[i]]=i;
    num=0;
    build(ro,1,n);
    while (m--){
        bo=read();
        if (bo==0) bo=read(),cg(ro,1,n,bo,o[read()-1]^ask(ro,1,n,bo)^(bo==1?0:ask(ro,1,n,bo-1)));else
        if (bo==1) if (bo=read(),x=read(),N[q]==-1) puts("0");else printf("%d\n",que(ro,1,n,bo,x,q));else
        if (rx=read(),ry=read(),x=o[read()-1],cg(ro,1,n,ry+1,ask(ro,1,n,ry)^(((ry-rx+1)&1)*x)),ca(ro,1,n,rx,ry,x,0,rx-1),rx-1) cg(ro,1,n,rx,ask(ro,1,n,rx-1));
    }
}

时间: 2024-08-24 02:03:06

BZOJ:4333: JSOI2012 智者的考验的相关文章

AC自动机 --- [JSOI2012]玄武密码

bzoj 4327 [JSOI2012]玄武密码 题目描述 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河. 相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此. 很多年后,人们终于在进香河地区发现了带有玄武密码的文字. 更加神奇的是,这份带有玄武密码的文字,与玄武湖南岸台城的结构有微妙的关联.于是,漫长的破译工作开始了. 经过分析,我们可以用东南西北四个方向来描述台城城砖的摆放,不妨用一个长度为N的序列来描述,序列中的元素

【BZOJ 4332】 4332: JSOI2012 分零食 (FFT+快速幂)

4332: JSOI2012 分零食 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 119  Solved: 66 Description 这里是欢乐的进香河,这里是欢乐的幼儿园. 今天是2月14日,星期二.在这个特殊的日子里,老师带着同学们欢乐地跳着,笑着.校长从幼儿园旁边的小吃店买了大量的零食决定分给同学们.听到这个消息,所有同学都安安静静地排好了队,大家都知道,校长不喜欢调皮的孩子. 同学们依次排成了一列,其中有A位小朋友,有三个共同的欢乐

bzoj千题计划309:bzoj4332: JSOI2012 分零食(分治FFT)

https://www.lydsy.com/JudgeOnline/problem.php?id=4332 因为如果一位小朋友得不到糖果,那么在她身后的小朋友们也都得不到糖果. 所以设g[i][j] 表示前i位小朋友,分到j个糖果,且前i位小朋友都分到糖果的方案数 令F(x) 表示分到x个糖果的欢乐程度 ∴g[i][j] = ∑ g[i-1][j-k]*F(k) 记g[i]=g[i-1]*F,则 g[i]=F ^ i 但是要求的是 Σ g[i][m] 记f[n]=Σ g[i]  i∈[1,n]

[BZOJ]1014 火星人prefix(JSOI2008)

一边听省队dalao讲课一边做题真TM刺激. BZOJ的discuss简直就是题面plus.大样例.SuperHINT.dalao题解的结合体. Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字符 m a d a m i m a d a m 现在,火星人定义了一个函数LCQ(x, y),表示:该字符串中第x个字符开始的字串

【BZOJ】【1014】【JLOI2008】火星人prefix

Splay/二分/Hash 看了网上的题目关键字(都不用点进去看……我也是醉了)了解到做法= =那就上呗,前面做了好几道Splay的题就是为了练手搞这个的. Hash判断字符串是否相同应该很好理解吧?>_>我就不细说了 二分这个相同前缀的长度应该也容易>_> 用Splay维护这个Hash值>_>……也挺简单的,跟据size域就能算出以x为根的子树的hash值了. 这次我终于发现了一个之前以为不太重要的点……让我WA了两次= =!! 就是Splay在执行完序列插入的时候,

bzoj 3757: 苹果树(树上莫队)

3757: 苹果树 Time Limit: 20 Sec  Memory Limit: 256 MB Submit: 1327  Solved: 510 [Submit][Status][Discuss] Description 神犇家门口种了一棵苹果树.苹果树作为一棵树,当然是呈树状结构,每根树枝连接两个苹果,每个苹果都可以沿着一条由树枝构成的路径连到树根,而且这样的路径只存在一条.由于这棵苹果树是神犇种的,所以苹果都发生了变异,变成了各种各样的颜色.我们用一个1到n之间的正整数来表示一种颜色

bzoj 1014 火星人prefix - 链表 - 分块

Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字符 m a d a m i m a d a m 现在,火星人定义了一个函数LCQ(x, y),表示:该字符串中第x个字符开始的字串,与该字符串中第y个字符开始的字串,两个字串的公共前缀的长度.比方说,LCQ(1, 7) = 5, LCQ(2, 10) = 1, LCQ(4,

BZOJ 1013: [JSOI2008]球形空间产生器sphere

二次联通门 : BZOJ 1013: [JSOI2008]球形空间产生器sphere /* BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元 QAQ SB的我也能终于能秒题了啊 设球心的坐标为(x,y,z...) 那么就可以列n+1个方程,化化式子高斯消元即可 */ #include <cstdio> #include <iostream> #include <cstring> #define rg register #define Max

bzoj 3309 DZY Loves Math - 莫比乌斯反演 - 线性筛

对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0. 给定正整数a,b,求sigma(sigma(f(gcd(i,j)))) (i=1..a, j=1..b). Input 第一行一个数T,表示询问数. 接下来T行,每行两个数a,b,表示一个询问. Output 对于每一个询问,输出一行一个非负整数作为回答. Sample Input 4 7558588 9653114 6514903 445