【BJOI2016】IP地址

追不到北京的神仙小姐姐(话说北京的神仙小姐姐长的好像我女神啊,不知道她去P了还是去T了呢),我只能颓废做北京省选了。。。。。。

咳咳,上面那句话不能让我女神看到。

题面

https://www.luogu.org/problem/P5460

题解

$[l,r]$变换了多少次等价于$[1,r]$-$[1,l-1]$,所以把所有的询问看成两个时间,离线处理。

把$trie$树看成线段树,相当于区间修改,单点查询。下传标记时,如果下面原来有标记,则失效。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

struct node{
  int ch[2],opt,add,v;
} trie[3200050];

struct question{
  int loc,time,ans,id;
  bool operator < (const question rhs) const {
    return time<rhs.time;
  }
} a[200050];
bool cmp(question a,question b){
  return a.id<b.id;
}

int n,q,cnt;
char s[100050][5],x[100050][35],qes[100050][35];

void insert(int x,char *p) {
  if (*p=='\0') return;
  if (!trie[x].ch[*p-'0']) {
    trie[x].ch[*p-'0']=++cnt;
    insert(cnt,p+1);
  } 
  else insert(trie[x].ch[*p-'0'],p+1);
}

int find(int x,char *p) {
  if (*p=='\0') return x;
  if (!trie[x].ch[*p-'0']) return x; else return find(trie[x].ch[*p-'0'],p+1);
}

void pushdown(int now){
  int k=trie[now].add;
  if (trie[now].ch[0] && !trie[trie[now].ch[0]].opt) trie[trie[now].ch[0]].v+=k,trie[trie[now].ch[0]].add+=k;
  if (trie[now].ch[1] && !trie[trie[now].ch[1]].opt) trie[trie[now].ch[1]].v+=k,trie[trie[now].ch[1]].add+=k;
  trie[now].add=0;
}

int cha(int now,int x,char *p){
  if (trie[now].add!=0) pushdown(now);
  if (now==x) return trie[now].v;
  return cha(trie[now].ch[*p-'0'],x,p+1);
}

void change(int now,int x,char *p){
  if (trie[now].add!=0) pushdown(now);
  if (now==x) {
    trie[now].v++;
    trie[now].add++;
    return;
  }
  change(trie[now].ch[*p-'0'],x,p+1);
}

int main(){
  int i,j,lb,rb,locb;
  scanf("%d %d",&n,&q);
  cnt=0;
  for (i=1;i<=n;i++) {
    scanf("%s %s",s[i],x[i]);
    insert(0,x[i]);
  }

  cnt=0;
  for (i=1;i<=q;i++) {
    scanf("%s %d %d",qes[i],&lb,&rb);
    locb=find(0,qes[i]);
    a[++cnt]=(question){locb,lb,0,2*i-1};
    a[++cnt]=(question){locb,rb,0,2*i};
  }
  sort(a+1,a+cnt+1);

  j=1;
  for (i=1;i<=n;i++) {
    int now=find(0,x[i]);
    change(0,now,x[i]);
    //trie[now].v++;
    //trie[now].add++;
    if (s[i][0]=='D') trie[now].opt=0; else if (s[i][0]=='A') trie[now].opt=1;
    for (;a[j].time==i && j<=cnt;j++) a[j].ans=cha(0,a[j].loc,qes[(a[j].id+1)/2]);
  }

  sort(a+1,a+cnt+1,cmp);
  for (i=1;i<=q;i++) {
    printf("%d\n",a[2*i].ans-a[2*i-1].ans);
  }
}

 

posted @ 2019-08-02 22:24  HellPix  阅读(311)  评论(0编辑  收藏  举报