hdu 5997 rausen loves cakes

来源:互联网 发布:斗鱼点播软件 编辑:程序博客网 时间:2024/06/14 12:43

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
 

Source
BestCoder Round #90


给你一个数列,有两种操作。

1、把所有值为a的改成b

2、询问[l,r]中一共有多少段



首先可以发现,段数肯定是越来越少。

考虑合并a,b。每次把小的并到大的上面,那么复杂度最终是log级别的

对于询问,我们把每段第一个位置赋值为1,用树状数组维护区间和。

暴力修改的时候顺便修改当前点的权值即可

#include<cstdio> #include<string>#include<cstring>#include<algorithm>using namespace std;struct line{int s,t;int next;}a[2000011];int head[1000011];int edge;inline void addedge(int s,int t){a[edge].next=head[s];head[s]=edge;a[edge].s=s;a[edge].t=t;}int tr[100011];int n;inline int lowbit(int x){return x&(-x);}inline void add(int x,int xx){int i;for(i=x;i<=n;i+=lowbit(i))tr[i]+=xx;}inline int ask(int x){int i,sum=0;for(i=x;i>=1;i-=lowbit(i))sum+=tr[i];return sum;}int col[100011],sz[1000011];int fx[1000011];int main(){int T;scanf("%d",&T);while(T>0){T--;int q;edge=0;memset(head,0,sizeof(head));memset(sz,0,sizeof(sz));memset(tr,0,sizeof(tr));scanf("%d%d",&n,&q);int i,j;for(i=1;i<=n;i++){scanf("%d",&col[i]);edge++;addedge(col[i],i);sz[col[i]]++;if(col[i]!=col[i-1])add(i,1);}for(i=1;i<=1000000;i++)fx[i]=i;int xx,x,y;for(i=1;i<=q;i++){scanf("%d%d%d",&xx,&x,&y);if(xx==1){int s=x,t=y;x=fx[x];y=fx[y];if(sz[x]>sz[y]){int tt=x;x=y;y=tt;tt=fx[s];fx[s]=fx[t];fx[t]=tt;}if(sz[x]==0||x==y)continue;int la=0;for(j=head[x];j!=0;j=a[j].next){int t=a[j].t;if(col[t]!=col[t-1])add(t,-1);if(t<=n-1&&col[t+1]!=col[t])add(t+1,-1);col[t]=y;if(col[t]!=col[t-1])add(t,1);if(t<=n-1&&col[t+1]!=col[t])add(t+1,1);la=j;}a[la].next=head[y];head[y]=head[x];head[x]=0;sz[y]+=sz[x];sz[x]=0;}elseprintf("%d\n",ask(y)-ask(x-1)+(col[x]==col[x-1]));}}return 0;}



0 0
原创粉丝点击