HDU5997-rausen loves cakes-树状数组+模拟

来源:互联网 发布:矩阵式项目组织形式 编辑:程序博客网 时间:2024/05/29 15:45

rausen loves cakes

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 279    Accepted Submission(s): 77

Problem Description
Rausen loves cakes. One day, he bought n cakes and the color of each cake is described as an integer in [1,1000000]. Rausen lines the cakes from left to right.

Before eating, rausen proceeds q operations on cakes.

At one time point, rausen would replace all cakes of x color with those of color y.

At another time point, rausen would calculate the number of segment colors in the interval[x,y]. A color segment is defined as an interval of one single color. For example,'1 4 4 1 1' involves 3 color segments.

Nevertheless, rausen finds that he cannot compile the statistics of color segments in the interval, which makes him weep like a helpless crybaby (bazinga). Please help rausen resolve the problem to placate him.

Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:

The first line contains 2 integers n,q.

In the following q lines,each line contains 3 integers: op(1op2)x and y which describe one operation:

If op=1, then rausen is to proceed a substitution operation and this is when you replace cakes of color x with those of color y.x and y satisfy (1x,y1000000).

if op=2, then rausen is to proceed a counting operation and this is when you are required to input the color segments in the interval [x,y].x and y satisfy (1xyn)

(1T5),(1n105),(1q105)

Output
For every counting operation of each case, a single line contains one number as the answer.

Sample Input
15 31 4 4 10 12 1 5 1 4 102 3 5

Sample Output
42


思路:暴利模拟,树状数组维护即可、

#include <queue>#include <functional>#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <stack>#include <vector>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>#include <assert.h>#define REP(i,k,n) for(int i=k;i<n;i++)#define REPP(i,k,n) for(int i=k;i<=n;i++)#define scan(d) scanf("%d",&d)#define scann(n,m) scanf("%d%d",&n,&m)#define mst(a,k)  memset(a,k,sizeof(a));#define LL long long#define eps 1e-8#define INF 0x3f3f3f3f#define inf INF*INF#define mod 1000000007using namespace std;#define N 100005#define M 1000005struct node{   int next;}no[M];int head[M];int n;int e[M];     //树状数组维护的数组int siz[M];   //siz[a] 数字a出现的次数int num[M];   //num[i] 第i位的数字int getsum(int tmp){   int ans = 0;   for(int i=tmp;i ;i -=i & -i) ans+=e[i];   return ans;}void update(int tmp,int change){    for(int i=tmp; i<=n; i+= i & -i) e[i]+=change;}int main(){   //freopen("in.txt","r",stdin);   int t;   scan(t);   while(t--){      int q;      scann(n,q);      num[0] = num[n+1] = -1;      mst(head,-1); mst(e,0); mst(siz,0);        REPP(i,1,n){        int a;scan(a);      num[i]=a;      siz[a]++;      no[i].next= head[a];      head[a] = i;      if(a!=num[i-1]) update(i,1);      }      while(q--){     //暴利模拟      int a,b,c;      scan(a); scann(b,c);      if(a==2) printf("%d\n",getsum(c) - getsum(b-1) + (int)(num[b-1]==num[b]));  //第2个操作      else{         if(b==c || !siz[b]) continue;         for(int i=head[b]; ~i; i=no[i].next){            if(num[i]!=num[i-1]) update(i,-1);   //撤销            if(num[i]!=num[i+1]) update(i+1,-1); //撤销            num[i] = c;                           //更新            if(num[i]!=num[i-1]) update(i,1);            if(num[i]!=num[i+1]) update(i+1,1);            if(no[i].next == -1){                 //注意是 no[i].next == -1 不是 i == -1               no[i].next = head[c]; head[c] = head[b]; head[b] = -1;  //将b 强塞进 c             break;            }         }         siz[c] += siz[b]; siz[b] = 0;         }      }   }}






0 0
原创粉丝点击