【CF1210D】Konrad and Company Evaluation(vector,图论)

题意:有i个人,m对两两之间的关系,第i个人初始的薪水为i,有q次操作,第i次操作会把v[i]号的薪水提升成n+i

如果两个人之间存在关系,薪水高的会向薪水低的炫耀

定义u,v,w为一个三元组,当u向v炫耀,v向w炫耀

要求每次操作后输出当前三元组个数

n,m,q<=1e5

思路:将人看成点,关系看成边,定义方向为从小到大

显然每次操作后被操作的人的薪水都会变成最大的,等价于将它的所有出边变成入边

答案即为所有点的入度*出度之和

vector暴力维护出边

学习了一下杜教的写法

势能分析见https://blog.csdn.net/Izumi_Hanako/article/details/101267502 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef unsigned int uint;
 5 typedef unsigned long long ull;
 6 typedef pair<int,int> PII;
 7 typedef pair<ll,ll> Pll;
 8 typedef vector<int> VI;
 9 typedef vector<PII> VII;
10 typedef pair<ll,ll>P;
11 #define N  200010
12 #define M  200010
13 #define fi first
14 #define se second
15 #define MP make_pair
16 #define pi acos(-1)
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
20 #define lowbit(x) x&(-x)
21 #define Rand (rand()*(1<<16)+rand())
22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
23 #define ls p<<1
24 #define rs p<<1|1
25 
26 const ll MOD=1e9+7,inv2=(MOD+1)/2;
27       double eps=1e-4;
28       int INF=1<<30;
29       ll inf=5e13;
30       int dx[4]={-1,1,0,0};
31       int dy[4]={0,0,-1,1};
32 
33 vector<int> c[N];
34 int d[N];
35 
36 int read()
37 {
38    int v=0,f=1;
39    char c=getchar();
40    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
41    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
42    return v*f;
43 }
44 
45 ll calc(int i)
46 {
47     int t=(int)c[i].size();
48     return 1ll*t*(d[i]-t);
49 }
50 
51 int main()
52 {
53     int n=read(),m=read();
54     rep(i,1,m)
55     {
56         int x=read(),y=read();
57         if(x>y) swap(x,y);
58         c[x].push_back(y);
59         d[x]++; d[y]++;
60     }
61     ll ans=0;
62     rep(i,1,n) ans+=calc(i);
63     printf("%I64d
",ans); 
64     int q=read();
65     rep(i,1,q)
66     {
67         int u=read();
68         ans-=calc(u);
69         for(int j=0;j<c[u].size();j++)
70         {
71             int v=c[u][j];
72             ans-=calc(v);
73             c[v].push_back(u);
74             ans+=calc(v);
75         }
76         c[u].clear();
77         printf("%I64d
",ans);
78     }
79 
80 
81 
82     return 0;
83 }
原文地址:https://www.cnblogs.com/myx12345/p/11581199.html