-
思路:容斥。如果不加限制的话,n个人m种信仰,则共有 种的排列方法,不合法的方案有 (第一个位置m种随便放,后面的从m-1种选出一个来即可),结果就是 。
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 5; const int mod = 100003; ll ksm(ll a,ll b){ ll ans = 1; while(b){ if(b&1) ans = ans*a%mod; a = a*a%mod; b = b >> 1; } return ans%mod; } int main(void) { ll m,n; cin >> m >> n; ll ans = ksm(m,n); ll ans1 = m*ksm(m-1,n-1); cout<<((ans-ans1)%mod+mod)%mod<<endl; return 0; }
-
思路:快速幂
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 5; int ksm(int a,int b,int mod){ int ans = 1; while(b){ if(b&1) ans = ans*a%mod; a = a*a%mod; b >>= 1; } return ans%mod; } int main(void) { int n,m,k,x; cin >> n >> m >> k >> x; int ans = ksm(10,k,n); cout<<(x+m*ans%n)%n<<endl; return 0; }
-
Wonderful Randomized Sum【贪心】
题意:给你一个数字序列,你可以选择它的一些前缀或后缀(可能是空的)中的每个数字都乘以-1。前缀和后缀可以交叉也可以为空。问能得到的最大序列和是多少。思路:应该可以看出,前缀和后缀交叉的情况下,交叉的那部分,相当于没有变化。 那么据题可知:
设前缀为A,后缀为B,未变化部分的为C。序列数字总和为S(允许A,B,C都为空的情况,此时A=B=C=0,
因为 A+B+C=S,需求解为 -(A+B)+C 的最大值,所以 —(A+B)+C的最大值 = —(S-C)+C的最大值 = 2C-S。综上 显然S是定值,我们要做的就是让C最大,问题就变成了求最大子段和了。
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 5; int a[maxn]; int main(void) { int n; cin >> n; int sum = 0; for(int i = 0; i < n; i++){ cin >> a[i]; sum += a[i]; } int ans = 0; int maxx = 0; for(int i = 0; i < n; i++){ ans += a[i]; if(ans < 0) ans = 0; if(ans>maxx) maxx = ans; } cout<<2*maxx-sum<<endl; return 0; }
-
题意:给一个长度为 n 的数组,输出 n-k-1 个数,分别为下标为 i 到 i+k-1 这个区间内存在且只出现一次的数的最大值,不存在则输出 “Nothing”。
思路:先把前 k 个数只出现一次的数存入 set 集合里,自动从小到大排序,如果不为空则输出最后一个数,否则输出 “Nothing”。 然后从 k+1 开始,每加入一个数就删去上一个区间的第一个数,并判断删去的数剩下的个数是否为 1,若是,则加入可行集合 set 里,否则就看它是否在可行集合里,在的话就删掉。 然后再判断新加入的数的个数是否为 1,是的话加入可行集合里,否则就看它是否在可行集合里,在的话就删掉。 最后再判断该区间的可行集合里是否为空,为空的话就输出 “Nothing”,否则输出最后一个数。
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 5; int a[maxn]; map<int,int> mp; set<int> s; int main(void) { int n,k; cin >> n >> k; for(int i = 1; i <= n; i++) cin >> a[i]; for(int i = 1; i <= n; i++){ if(i<=k){ mp[a[i]]++; if(mp[a[i]]==1) s.insert(a[i]); else{ s.erase(a[i]); } if(i==k){ if(s.empty()) cout<<"Nothing"<<endl; else cout<<*(--s.end())<<endl; } } else{ mp[a[i]]++; mp[a[i-k]]--; if(mp[a[i]]==1) s.insert(a[i]); else s.erase(a[i]); if(mp[a[i-k]]==1) s.insert(a[i-k]); else s.erase(a[i-k]); if(s.empty()) cout<<"Nothing"<<endl; else cout<<*(--s.end())<<endl; } } return 0; }
『日常训练』2020WFU个人积分赛第二场
猜你喜欢
转载自blog.csdn.net/wxd1233/article/details/105572612
今日推荐
周排行