P1483 序列变换(标记处理)

传送门

思路:标记的运用。显然对于每次操作2:只需用该数加上该数因子被标记的值即可。

一开始算时间复杂度: O ( n + m + m n ) O(n+m+m\sqrt{n}) O(n+m+mn )以为爆掉了。。

细细一算 n n n最大 1 e 6 1e6 1e6, m m m最大 1 e 5 1e5 1e5,操作二保证不多于 1 e 4 1e4 1e4

m n m\sqrt{n} mn 最大是 1 e 7 1e7 1e7

总共加起来不超过 1 e 8 1e8 1e8。居然能过。
洛谷的评测机真的强

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
#define mst(a) memset(a,0,sizeof a)
ll a[N];
int n,m;
map<int,ll>mp; 
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]); //用%d 无限WA。。。 
	while(m--){
		int op,x,y;
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d",&x,&y);
			mp[x]+=y;
		}
		else {
			scanf("%d",&x);
			ll ans=a[x];
			for(int i=1;i*i<=x;i++){
				 if(x%i==0){
				 	 if(mp[i])
					 ans+=mp[i];
					 if(i*i!=x&&mp[x/i]) ans+=mp[x/i];
				 }
			}
			printf("%lld\n",ans);
		}
	}
	return 0;
}