首页 > 其他 > 详细

BZOJ4628 BJOI2016IP地址(trie)

时间:2019-01-04 13:43:23      阅读:134      评论:0      收藏:0      [点我收藏+]

  离线,每次修改相当于对该规则的所有匹配点的值+1,考虑在trie上打加法标记和匹配标记,匹配标记不下传,加法标记下传遇到匹配标记时清空。注意是用b时刻前缀-a时刻前缀,而不是(a-1)时刻前缀,具体我也不知道为啥可能是我没看懂题。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define N 100010
char getc(){char c=getchar();while ((c<A||c>Z)&&(c<a||c>z)&&(c<0||c>9)) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<0||c>9) {if (c==-) f=-1;c=getchar();}
    while (c>=0&&c<=9) x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
int n,m,cnt,ans[N],root;
struct data{int ch[2],x,tag,lazy;
}tree[N<<6];
struct bit{int x,n,id;};
struct data2{int op;bit ip;
}q[N];
bit gettwo()
{
    unsigned int x=0,cnt=0;char c=getchar();
    while (c<0||c>9) c=getchar();
    while (c>=0&&c<=1) x+=(c^48)<<cnt,cnt++,c=getchar();
    return (bit){x,cnt};
}
vector<bit> INS[N],DEL[N];
void update(int k,int x){if (!tree[k].tag) tree[k].x+=x,tree[k].lazy+=x;}
void down(int k)
{
    if (!tree[k].ch[0]) tree[k].ch[0]=++cnt;
    update(tree[k].ch[0],tree[k].lazy);
    if (!tree[k].ch[1]) tree[k].ch[1]=++cnt;
    update(tree[k].ch[1],tree[k].lazy);
    tree[k].lazy=0; 
}
void ins(int &k,bit x,int p)
{
    if (!k) k=++cnt;
    if (p==x.n) {update(k,1),tree[k].tag++;return;}
    if (tree[k].lazy) down(k);
    ins(tree[k].ch[(x.x&(1<<p))>0],x,p+1);
}
void del(int &k,bit x,int p)
{
    if (!k) k=++cnt;
    if (p==x.n) {tree[k].tag--,update(k,1);return;}
    if (tree[k].lazy) down(k);
    del(tree[k].ch[(x.x&(1<<p))>0],x,p+1);
}
int query(int k,bit x,int p)
{
    if (!k) return 0;
    if (p==x.n) return tree[k].x;
    if (tree[k].lazy) down(k);
    return query(tree[k].ch[(x.x&(1<<p))>0],x,p+1);
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("bzoj4628.in","r",stdin);
    freopen("bzoj4628.out","w",stdout);
    const char LL[]="%I64d\n";
#else
    const char LL[]="%lld\n";
#endif
    n=read(),m=read();
    for (int i=1;i<=n;i++)
    {
        char c=getc();if (c==A) q[i].op=1;else q[i].op=-1;
        q[i].ip=gettwo();
    }
    for (int i=1;i<=m;i++)
    {
        bit x=gettwo();x.id=i;
        DEL[read()].push_back(x);
        INS[read()].push_back(x);
    }
    for (int i=1;i<=n;i++)
    {
        if (q[i].op==1) ins(root,q[i].ip,0);else del(root,q[i].ip,0);
        for (int j=0;j<INS[i].size();j++) ans[INS[i][j].id]+=query(root,INS[i][j],0); 
        for (int j=0;j<DEL[i].size();j++) ans[DEL[i][j].id]-=query(root,DEL[i][j],0);
        //for (int j=1;j<=cnt;j++) cout<<tree[j].ch[0]<<‘ ‘<<tree[j].ch[1]<<‘ ‘<<tree[j].x<<‘ ‘<<tree[j].tag<<‘ ‘<<tree[j].lazy<<endl;cout<<endl;
    }
    for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
    return 0;
}

 

BZOJ4628 BJOI2016IP地址(trie)

原文:https://www.cnblogs.com/Gloid/p/10213792.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!