A 欧几里得
代码:
#includeusing namespace std; long a[1000]; long b[1000]; int main(){ int t; cin>>t; a[0] =0; a[1] = 1; for(int i=2;i<=1000;i++){ a[i] = a[i-1]+a[i-2]; } b[0] =1; for(int i=1;i<=998;i++){ b[i] = a[i+1]+a[i+2]; } for(int i=1;i<=t;i++){ int n; cin>>n; cout<endl; } return 0; }
B.括号序列
代码:
#include#include<string.h> #include if(s[i]=='('||s[i]=='['||s[i]=='{') a.push(s[i]); else if(s[i]==')'&&!a.empty()&&a.top()=='(') a.pop(); else if(s[i]=='}'&&!a.empty()&&a.top()=='{') a.pop(); else if(s[i]==']'&&!a.empty()&&a.top()=='[') a.pop(); else{ cout<<"No"<<endl; return 0; } } if(a.empty()) cout<<"Yes"<<endl; else cout<<"No"<<endl; return 0; }using namespace std; typedef long long ll; int main(){ string s; cin>>s; ll len = s.length(); stack<char> a; if(!a.empty()) a.pop(); for(int i=0;i ){
C子段乘积
代码:
#includeusing namespace std; const int mod = 998244353; const int maxn = 2e5+10; typedef long long ll; ll a[maxn]; ll ans; ll Power(ll x,ll y){ ll res =1; while(y){ if(y&1) res=res*x%mod; x=x*x%mod; y>>=1; } return res; } int main(){ ll n,k; cin>>n>>k; for(int i=1;i<=n;i++) scanf("%lld",&a[i]); ll temp = 1; for(int l=1,r=1;r<=n;r++){ if(!a[r]){ temp=1,l=r+1; continue; } temp =temp*a[r]%mod; while(r-l+1>k){ temp =temp*Power(a[l],mod-2)%mod; l++; } if(r-l+1==k) ans = max(ans,temp); } cout< return 0; }endl;
D子段异或
思路:
例子:
a 0 2 1 3 2 1
0 0^2=2 2^1=3 3^3=0 0^2=2 2^1=3
0: 2次 2:2次 3:2次
子段异或为0:[1,1] , [2,4] , [1,4] , [3,5] , [4,6]
0 2 1 3 0 2 1 3 1 3 2 3 2 1
答案是:5 = 1+0+0+2+1+1
a^b=a 则b=0 异或数值为第一个a的区间[l1,r1],异或数值为第二个a的区间[l1,r2],则异或数值为b的区间为[r1+1,r2]
就[3,5]这个区间来说,[1,2]这个区间的异或的值为2,[3,5]区间的异或值为0,2^(1^3^2)=2, 2这个数值出现的次数为2次,ans+=(2-1);
因此题目询问异或值为0的区间有多少个,区间[l,r]中1<=l<=r<=n,l可以等于r,所以初始化mp[0]=1,本身就算一个。
代码:
#include#include return 0; }
E.最小表达式
代码:
#include#include<string.h> #include if(s[i]=='+') sum++; } ll n = len-1; ll cnt = sum+1;//被分为cnt个数 ll k=0; ll y; ll m=0; while(n>=sum){//保证不遍历到加号 ll x = 0; for(int i=1;i<=cnt;i++){ x+=(s[n--]-'0'); if(n<sum) break; } x+=y; a[m++] = x%10; y = x/10; } if(y!=0)//跳出循环的时候y的值需要判断 cout<<y; for(ll i=m-1;i>=0;i--) cout<<a[i]; cout<<endl; return 0; }using namespace std; typedef long long ll; const int maxn =5e5+10; ll a[maxn]; char s[maxn]; int main(){ scanf("%s",s); ll len = strlen(s); sort(s,s+len);//char类型也可以排序,加号排在数字的前面 ll sum=0; for(ll i=0;i ){
F 树上博弈
思路:
用样例一来说:如图:节点数为偶数为sum[1],节点数为奇数为sum[0].
只要牛牛和牛妹所在节点之间的距离为偶数,即牛牛会赢。
所以答案就是节点数为偶数的sum[1]*(sum[1]-1)+节点数为奇数的sum[0]*(sum[0]-1)。
代码:
#include#include %2]++; bfs(road[now][i],dis+1); } return ; } int main(){ ll n; cin>>n; sum[0] = 1;//根节点为1,初始化sum[0]=1; for(int i=2;i<=n;i++){ int t; scanf("%d",&t); road[t].push_back(i); } bfs(1,1); ll ans = sum[0]*(sum[0]-1)+sum[1]*(sum[1]-1); cout<using namespace std; typedef long long ll; const int maxn = 1e6+10; vector<int> road[maxn]; ll sum[3]; void bfs(int now,int dis){ for(int i=0;i ){ sum[dis endl; return 0; }