A 欧几里得
代码:
#include<iostream>
using 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<<b[n]<<endl;
}
return 0;
}
B.括号序列
代码:
#include<iostream>
#include<string.h>
#include<stack>
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<len;i++){
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;
}
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<iostream>
#include<map>
#include<stdio.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+10;
ll a[maxn];
map<ll,ll>mp;
int main(){
int n;
cin>>n;
ll ans= 0;
mp[0]=1;
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
a[i]^=a[i-1];
ans+=mp[a[i]];
mp[a[i]]++;
}
cout<<ans<<endl;
return 0;
}