Codeforces 杂题选讲 #1
作者:互联网
1715C Monoblock
展开
题意简述:
我们定义连续 \(k\)(\(k\) 尽可能大)个相同的数被称为一个“块”。一个序列的“块”数就相当于将其直接去重后的序列长度。
给定一个长度 \(n\) 的序列和 \(m\) 次询问。对于每次询问,有两个数 \(i,x\),先将 \(a_i\) 改为 \(x\),然后输出 \(\sum\limits_{l=1}^n\sum\limits_{r=l}^ng(l,r)\),其中 \(g(l,r)\) 表示 \(a_{l\sim r}\) 的“块”数。
解法:
记 \(ans\) 为当前答案。
考虑当 \(a_i \neq a_{i-1}\) 时,会有哪些区间的值发生增加 \(1\) 的变化(以 \(a_4 \neq a_3\) 举例):
由此推出当 \(a_i \neq a_{i-1}\) 时,对答案的贡献为 \((i-1)*(n-i+1)\)
每次修改时判断被改元素左右的变化情况,并依上式维护即可。注意 \(ans\) 初始化为 \(\frac{n(n+1)}{2}\) 即可
#include <cstdio>
#include <algorithm>
#include <cstring>
#define re register
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f;
const double eps=1e-8;
inline int gcd(int x,int y){return y==0?x:(x>y?gcd(y,x%y):gcd(x,y%x));}
inline ll read(){
char ch=getchar();ll x=0;//bool sgn=false;
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x;
}
const int MAXN=1e5+5;
ll n,m,a[MAXN],ans,x,v;
int main(){
n=read();m=read();ans=n*(n+1)/2;
for(re int i=1;i<=n;++i){
a[i]=read();
if(i!=1&&a[i]!=a[i-1]) ans+=(i-1)*(n-i+1);
}
bool pre1,pre2;
while(m--){
x=read();v=read();
if(a[x]==a[x-1]) pre1=true;
else pre1=false;
if(a[x]==a[x+1]) pre2=true;
else pre2=false;
a[x]=v;
if(pre1&&a[x]!=a[x-1]) ans+=(x-1)*(n-x+1);
else if(!pre1&&a[x]==a[x-1]) ans-=(x-1)*(n-x+1);
if(pre2&&a[x]!=a[x+1]) ans+=x*(n-x);
else if(!pre2&&a[x]==a[x+1]) ans-=x*(n-x);
printf("%lld\n",ans);
}
return 0;
}
标签:ch,gcd,int,ll,选讲,Codeforces,include,杂题,neq 来源: https://www.cnblogs.com/chroneZ/p/16695140.html