初次接触分块思想
来源:互联网 发布:勇敢一点 薛之谦 知乎 编辑:程序博客网 时间:2024/05/19 00:56
先来个稍简单的分块题:
codeforces 86 D. Powerful array
Let's sort the query intervals according to the following rule: first come the intervals with the left ends in Q_1, then the intervals with the left ends in Q_2, and so on. And if the left ends of the two queries belong to the same part, then the interval with the more left right end is assumed to be smaller.
In order to prove the stated asymptotic behavior we will follow the steps of the left and the right ends independently. We note that the left ends that belong to the same Q_i make <= n / p steps, and transition to Q_{i+1} costs no more than 2 * n / p steps. Therefore the left ends make <= n/p * n + 2*n steps (the second summand is O(n), and it's negligible).
The right ends in the common group move only to the right, and this proves <= n * p steps (during the whole process) estimate. We will estimate the transition to the next Q_i at no more than n steps, so overall we get < = 2 * n * p steps.
Thus, the total number of steps is no more than (n / p * n + 2 * n * p). Now we choose p = sqrt(n) which proves the statement.
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>using namespace std;typedef long long LL;const int N=2e5+10,M=1e6+10;int a[N],cnt[M];struct node{ int x,y,l,dex;}edge[N];int cmp(node a,node b){ return a.l<b.l||(a.l==b.l&&a.y<b.y) ;}LL ans,res[N];int L,R;void query(int x,int y,int dex){ if(dex){ for(int i=L;i<x;i++){ cnt[a[i]]--; ans=ans-((cnt[a[i]]<<1)+1)*a[i]; } for(int i=x;i<L;i++){ ans=ans+((cnt[a[i]]<<1)+1)*a[i]; cnt[a[i]]++; } for(int i=R+1;i<=y;i++){ ans=ans+((cnt[a[i]]<<1)+1)*a[i]; cnt[a[i]]++; } for(int i=y+1;i<=R;i++){ cnt[a[i]]--; ans=ans-((cnt[a[i]]<<1)+1)*a[i]; } } else { for(int i=x;i<=y;i++) { ans=ans+((cnt[a[i]]<<1)+1)*a[i]; cnt[a[i]]++; } } L=x; R=y;}int main(){ //freopen("cin.txt","r",stdin); int n,t; while(cin>>n>>t){ int len=sqrt(1.0*n); memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=0;i<t;i++){ scanf("%d%d",&edge[i].x,&edge[i].y); edge[i].dex=i; edge[i].l=(edge[i].x-1)/len; } sort(edge,edge+t,cmp); ans=0; for(int i=0;i<t;i++){ query(edge[i].x,edge[i].y,i); res[edge[i].dex]=ans; } for(int i=0;i<t;i++){ printf("%I64d\n",res[i]); } } return 0;}
这是那道和mobius相关的题:
#include <iostream>#include <cstdio>using namespace std;typedef long long LL;const int N=1e7+10;int mu[N],pri[N/10],cnt=0;bool vis[N];LL sum[N];void getmu(){ mu[1]=1; for(int i=2;i<N;i++){ if(!vis[i]){ mu[i]=-1; pri[cnt++]=i; } for(int j=0;j<cnt&&pri[j]*i<N;j++){ vis[i*pri[j]]=1; if(i%pri[j]==0){ mu[i*pri[j]]=0; break; } else mu[i*pri[j]]=-mu[i]; } } for(int i=1;i<N;i++){ if(mu[i]){ for(int j=0;i*pri[j]<N&&j<cnt;j++){ sum[i*pri[j]]+=mu[i]; } } } for(int i=1;i<N;i++){ sum[i]+=sum[i-1]*1LL; }}int main(){ //freopen("cin.txt","r",stdin); int a,b,t; getmu(); cin>>t; while(t--){ scanf("%d%d",&a,&b); if(a>b){ a=a^b; b=a^b; a=a^b; } LL ans=0; for(int i=1;i<=a;i++){ //10/4=2; 10/2=5; int t1=a/i,t2=b/i; int next=min(a/t1,b/t2); ans=ans+1LL*t1*t2*(sum[next]-sum[i-1]); i=next; } printf("%lld\n",ans); } return 0;}
- 初次接触分块思想
- 初次接触
- 初次接触
- 初次接触
- 分块思想
- 初次接触EJB
- 初次接触MFC
- 《英雄无敌 V》初次接触!
- 初次接触linux 总结:
- 初次接触power architecture
- 初次接触Hibernate
- 初次接触Hibernate
- 初次接触GDIplus
- 初次接触ASP.NET
- 初次接触asp.net
- WAP初次接触
- 初次接触XSL
- 初次接触Oracle
- MM模块中常用到的透明表
- OpenStack设计与实现(三)KVM和QEMU浅析
- Java包装类、自动装箱与拆箱知识总结
- ADS中debug,debugrel,release三个版本的区别
- 如何让spring mvc web应用启动时就执行特定处理
- 初次接触分块思想
- 删除windows下过长路径的目录
- 一个简易的具有点击方法的UIImageView的封装
- 让那些白骨,别忘了回家
- Android四大基本组件介绍与生命周期
- 在信号处理函数中调用非可重入函数getpwnam
- 避免缓冲区溢出攻击的方法
- gradle DSL method not found: android()
- found pre-existing rpmdb problem