【线段树】 FZU 2105 Digits Count

来源:互联网 发布:赵敏 情趣 知乎 编辑:程序博客网 时间:2024/05/22 12:36

点击打开链接

因为单个数最大为15 所以可以将一个数分成四位

因为SUM 和OR 操作会霸气的将区间内变成全0 或全1 

所以需要清空col数组

而XOR不需要

Pushdown时同理,而且需要注意顺序。因为只有(先SUM或OR 再 XOR操作)这种可能 才会在同一个结点上有两个标记

#include <cstdio>#include <cstring>#include <cstdlib>#include <string>#include <iostream>#include <algorithm>#include <sstream>#include <cmath>using namespace std;#include <queue>#include <stack>c#include <set>#include <vector>#include <deque>#include <map>#define cler(arr, val)    memset(arr, val, sizeof(arr))#pragma comment(linker, "/STACK:102400000,102400000")typedef long long  LL;const int MAXN = 1020200;const int MAXM = 140000;const int INF = 0x3f3f3f3f;const int mod = 1000000007;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int sum[MAXN<<2][4],col[4][3][MAXN<<2],a,num;void pushdown(int rt,int x){    for(int i=0;i<4;i++)    {        if(col[i][1][rt])//or        {            col[i][0][rt<<1]=0;            col[i][0][rt<<1|1]=0;            col[i][1][rt<<1]=1;            col[i][1][rt<<1|1]=1;            col[i][2][rt<<1]=0;            col[i][2][rt<<1|1]=0;            sum[rt<<1][i]=x-(x>>1);            sum[rt<<1|1][i]=x>>1;        }        else if(col[i][2][rt])//and        {            col[i][0][rt<<1]=0;            col[i][0][rt<<1|1]=0;            col[i][1][rt<<1]=0;            col[i][1][rt<<1|1]=0;            col[i][2][rt<<1]=1;            col[i][2][rt<<1|1]=1;            sum[rt<<1][i]=0;            sum[rt<<1|1][i]=0;        }        if(col[i][0][rt])//xor        {            col[i][0][rt<<1]^=1;            col[i][0][rt<<1|1]^=1;            sum[rt<<1][i]=(x-(x>>1))-sum[rt<<1][i];            sum[rt<<1|1][i]=(x>>1)-sum[rt<<1|1][i];        }        col[i][0][rt]=0;        col[i][1][rt]=0;        col[i][2][rt]=0;    }}void pushup(int rt){    for(int i=0;i<4;i++)        sum[rt][i]=sum[rt<<1][i]+sum[rt<<1|1][i];}void build(int l,int r,int rt){    for(int i=0;i<4;i++)        col[i][0][rt]=col[i][1][rt]=col[i][2][rt]=0;    if(l==r)    {        scanf("%d",&a);        for(int i=0;i<4;i++)            sum[rt][i]=(a&(1<<i))?1:0;        return ;    }    int m=(l+r)>>1;    build(lson);    build(rson);    pushup(rt);}void update(int L,int R,int l,int r ,int rt,int x){    if(L<=l&&r<=R)    {        for(int i=0;i<4;i++)        {            int c=(x&(1<<i))?1:0;            if(num==2&&c==0)//and            {                sum[rt][i]=0;                col[i][0][rt]=0;                col[i][1][rt]=0;                col[i][num][rt]=1;            }            else if(num==1&&c)//or            {                sum[rt][i]=r-l+1;                col[i][0][rt]=0;                col[i][num][rt]=1;                col[i][2][rt]=0;            }            else if(num==0&&c)//xor            {                sum[rt][i]=(r-l+1)-sum[rt][i];                col[i][num][rt]^=1;            }        }        return ;    }    pushdown(rt,r-l+1);    int m=(l+r)>>1;    if(L<=m)   update(L,R,lson,x);    if(m<R)   update(L,R,rson,x);    pushup(rt);}int query(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R)    {        int val=0;        for(int i=0;i<4;i++)            val+=sum[rt][i]*(1<<i);        return val;    }    pushdown(rt,r-l+1);    int ans=0;    int m=(l+r)>>1;    if(L<=m)  ans+=query(L,R,lson);    if(m<R)   ans+=query(L,R,rson);    return ans;}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);    //  freopen("out.txt", "w", stdout);#endif    int n,m,t,l,r;    char s[10];    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        build(1,n,1);        while(m--)        {            scanf("%s",s);            if(s[0]=='S')            {                scanf("%d%d",&l,&r);                printf("%d\n",query(l+1,r+1,1,n,1));            }            else            {                int x;                scanf("%d%d%d",&x,&l,&r);                if(s[0]=='X')                    num=0;                if(s[0]=='O')                    num=1;                if(s[0]=='A')                    num=2;                update(l+1,r+1,1,n,1,x);            }        }    }    return 0;}


0 0
原创粉丝点击