公主的朋友

来源:互联网 发布:linux ifup eth0 失败 编辑:程序博客网 时间:2024/04/29 01:21

题目描述

由于 Wulala 在上个问题中的精彩表现,公主认为 Wulala 是一个很棒的人,就把 Wulala 留在了 X 国。这时正好公主的一位传教士朋友来拜访公主,于是想找 wulala 帮忙X 国如同一条直线,其中有 n 个城市,从东向西分别编号为 1~n。而他的国家中有 m 种宗教,每个城市一定会有一种信仰的宗教。

有时候有些城市为了获得更多的认可,会派出信仰本城市宗教的传教士前往其他国家。X 国

的传教士都十分厉害,只要是他途经的地方都会改信他所传播的宗教。

传教士们在路上碰到自己宗教的城市自然就不用传教了,可以停下来看看里番啥的,所以每

一个传教士在旅行前都会计算自己可以在多少城市停下来(不包括起始的城市)。

而传教士们都是文科僧,数学是很差的,所以他希望 Wulala 能帮他计算。可 Wulala 数学也不好,但他又不想在公主面前丢脸,你能帮帮他吗?

输入

第一行两个整数 n,m

第二行 n 个整数第 i 个整数代表第 i 各城市信仰的宗教

第三行一个整数 T 代表传教士的个数

接下来 T 行每行两个整数 x,y 代表 x 城向 y 城派遣了一个传教士(保证 x < y)

输出

输出 T 行,第 i 行代表第 i 个传教士询问的答案

样例输入

2 21 221 21 2

样例输出

01

提示


对于 30%的数据 n <= 100000, m <= 10, T <= 100



对于 60%的数据 n <= 100000, m <= 10, T <= 100000



对于 100%的数据 n <= 100000, m <= 300, T <= 100000

正解给的是分块,那就没什么好说的了,每次区间修改直接打标记就可以了,注意暴力修改散点以前下传标记

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#define maxn 100005using namespace std;int n,m,blo,T;int bl[maxn],L[maxn],R[maxn];int mark[maxn],a[maxn];int read(){   int x=0;   char ch=getchar();   while(ch<'0'||ch>'9') ch=getchar();   while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}   return x;  }int quiry(int x,int y){    int ans=0;    if(mark[bl[x]]){        ans+=min(R[bl[x]],y)-x;        for(int i=L[bl[x]];i<=R[bl[x]];i++) a[i]=mark[bl[x]];        mark[bl[x]]=0;    }    else{        for(int i=x+1;i<=min(R[bl[x]],y);i++)          if(a[x]==a[i]) ans++;  else a[i]=a[x];    }    if(bl[x]!=bl[y]){      if(mark[bl[y]]){           if(mark[bl[y]]==a[x]) ans+=y-L[bl[y]]+1;           else{             for(int i=L[bl[y]];i<=y;i++) a[i]=a[x];             for(int i=y+1;i<=R[bl[y]];i++) a[i]=mark[bl[y]];             mark[bl[y]]=0;           }      }       else{         for(int i=L[bl[y]];i<=y;i++)         if(a[i]==a[x]) ans++;         else a[i]=a[x];      }    }    for(int i=bl[x]+1;i<=bl[y]-1;i++){        if(mark[i]){           if(mark[i]==a[x]) ans+=R[i]-L[i]+1;        }        else{              for(int j=L[i];j<=R[i];j++)              if(a[j]==a[x]) ans++;              else a[j]=a[x];        }        mark[i]=a[x];    }    return ans;}int main(){    scanf("%d%d",&n,&m);    blo=(int)sqrt(n);     for(int i=1;i<=n;i++){        scanf("%d",&a[i]);       bl[i]=(i-1)/blo+1;    }    for(int i=1;i<=bl[n];i++){ L[i]=(i-1)*blo+1; R[i]=min(i*blo,n); }    scanf("%d",&T);    int x,y,ans;    for(int i=1;i<=T;i++){        x=read();y=read();        ans=quiry(x,y);        printf("%d\n",ans);    }    //while(1);    return 0;}


原创粉丝点击