CF 1322C Instant Noodles

https://codeforces.com/problemset/problem/1322/C

快乐

核心在于    gcd(a,b)  ==  gcd(a+b,a,b)

加法不会影响和的gcd,所以本质就不是那么多了

既然是gcd,那就枚举出左边尽可能不重合的右边权值的GCD吧,

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
#include<sstream>
#include<string>
#include<map>
using namespace std;
const int maxn = 2e6+11;
const int N = 5e5+11;
typedef long long ll;

string sn;
string cal(int x){
	string a;
	while(x){ int t = x%10 + '0';a.push_back(t);x/=10;}
	return a;
}
vector<string>ans;
map<string,ll>cns;

vector<int>G[maxn],ins[maxn];

void add(int be,int en){
	G[be].push_back(en);
}
ll list[maxn];




int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;i++) {
			G[i].clear(),ins[i].clear();
			list[i] = 0;
			G[i+N].clear();
		}
		for(int i=1;i<=n;i++){
			scanf("%lld",&list[i]);
		}
		for(int i=0;i<m;i++){
			int be,en;
			scanf("%d%d",&be,&en);
			be += N;
			add(en,be);
		}
		
		for(int i=1;i<=n;i++){
			for(int j=0;j<G[i].size();j++){
				int p = G[i][j];
				ins[i].push_back(p-N);
			}
		}
		ans.clear();
		cns.clear();
		
		for(int i=1;i<=n;i++){
			sort(ins[i].begin(),ins[i].end());
			sn.clear();
			
			for(int j=0;j<ins[i].size();j++){
				int p = ins[i][j];
				sn += cal(p);
				sn += "#";	
			}
			if(sn.size() == 0) continue;
			ans.push_back(sn);
			cns[sn] += list[i];
		}
		ll d;
		for(int i=0;i<ans.size();i++){
			if(i == 0) d = cns[ans[i]];
			else{
				d = __gcd(d,cns[ans[i]]);
			}
		}
		printf("%lld
",d);
		
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/lesning/p/14047281.html