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.
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(1≤op≤2) , 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 (1≤x,y≤1000000) .
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 (1≤x≤y≤n)
(1≤T≤5) , (1≤n≤105) , (1≤q≤105)
The first line contains 2 integers n , q .
In the following q lines,each line contains 3 integers: op(1≤op≤2) , 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 (1≤x,y≤1000000) .
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 (1≤x≤y≤n)
(1≤T≤5) , (1≤n≤105) , (1≤q≤105)
Output
For every counting operation of each case, a single line contains one number as the answer.
Sample Input
1 5 3 1 4 4 10 1 2 1 5 1 4 10 2 3 5
Sample Output
4 2
思路:暴利模拟,树状数组维护即可、
#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 1000000007
using namespace std;
#define N 100005
#define M 1000005
struct 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;
}
}
}
}