2020ICPC济南站部分题解
作者:互联网
A题
看出独立性后高斯消元
#include<bits/stdc++.h> using namespace std; #define ll long long const int N=205; int a[N][N];//增广矩阵 int x[N];//解集 int freeX[N];//自由变元 int Gauss(int equ,int var){//返回自由变元个数 /*初始化*/ for(int i=0;i<=var;i++){ x[i]=0; freeX[i]=0; } /*转换为阶梯阵*/ int col=0;//当前处理的列 int num=0;//自由变元的序号 int row;//当前处理的行 for(row=0;row<equ&&col<var;row++,col++){//枚举当前处理的行 int maxRow=row;//当前列绝对值最大的行 for(int i=row+1;i<equ;i++){//寻找当前列绝对值最大的行 if(abs(a[i][col])>abs(a[maxRow][col])) maxRow=i; } if(maxRow!=row){//与第row行交换 for(int j=row;j<var+1;j++) swap(a[row][j],a[maxRow][j]); } if(a[row][col]==0){//col列第row行以下全是0,处理当前行的下一列 freeX[num++]=col;//记录自由变元 row--; continue; } for(int i=row+1;i<equ;i++){ if(a[i][col]!=0){ for(int j=col;j<var+1;j++){//对于下面出现该列中有1的行,需要把1消掉 a[i][j]^=a[row][j]; } } } } /*求解*/ //无解:化简的增广阵中存在(0,0,...,a)这样的行,且a!=0 for(int i=row;i<equ;i++) if(a[i][col]!=0) return -1; //无穷解: 在var*(var+1)的增广阵中出现(0,0,...,0)这样的行 int temp=var-row;//自由变元有var-row个 if(row<var)//返回自由变元数 return temp; //唯一解: 在var*(var+1)的增广阵中形成严格的上三角阵 for(int i=var-1;i>=0;i--){//计算解集 x[i]=a[i][var]; for(int j=i+1;j<var;j++) x[i]^=(a[i][j]&&x[j]); } return 0; } int A[N][N],B[N][N]; ll ksm(ll x,ll y,ll m){ ll res=1; while(y){ if(y&1)res=res*x%m; x=x*x%m; y>>=1; } return res; } int main(void) { int n;scanf("%d",&n); for(int i=0;i<n;i++){ for(int j=0;j<n;j++)scanf("%d",&A[i][j]); } for(int i=0;i<n;i++){ for(int j=0;j<n;j++)scanf("%d",&B[i][j]); } long long ean=0; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ for(int k=0;k<n;k++){ if(j==k)a[j][j]=A[j][j]^B[j][i]; else a[j][k]=A[j][k]; } } int freeNum=Gauss(n,n);//获取自由元 if(freeNum == -1) continue; else ean+=freeNum; } cout<<ksm(2ll,ean,1ll*998244353); return 0; }View Code
C题
答案和3无关,只要考虑1和2的相对大小求解即可
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=1e6+10; ll a[N]; int main(){ ios::sync_with_stdio(false); int i; ll ans=0; for(i=1;i<=3;i++){ cin>>a[i]; } if(a[1]>=a[2]){ ans+=2*a[2]; a[1]-=a[2]; ans+=3*(a[1]/3); if(a[1]%3==2){ ans+=1; } cout<<ans<<endl; } else{ ans+=2*a[1]; a[2]-=a[1]; ans+=6*(a[2]/3); if(a[2]%3==2){ ans+=4; } cout<<ans<<endl; } return 0; }View Code
D题
刚开始是全部取右边,因此我们排序后控制自己的位置不能小于前面一个人的位置,在这种情况下取最小
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=1e6+10; int l[N],r[N]; struct node{ int x,low; bool operator <(const node &t) const{ if(x!=t.x) return x<t.x; return low>t.low; } }s[N]; ll w[N]; int main(){ ios::sync_with_stdio(false); int i; int n; cin>>n; for(i=1;i<=n;i++){ cin>>l[i]>>r[i]; s[i].x=r[i]; s[i].low=l[i]; } ll ans=0; for(i=1;i<=n;i++){ ans+=s[i].x; } sort(s+1,s+1+n); int lst; for(i=1;i<=n;i++){ int tmp=0; if(i==1){ tmp=s[i].x-s[i].low; lst=s[i].low; ans-=tmp; continue; } if(s[i].x==s[i-1].x){ tmp=min(s[i].x-s[i].low,s[i].x-lst); } else{ tmp=min(s[i].x-s[i].low,s[i].x-lst); } ans-=tmp; lst=s[i].x-tmp; } cout<<ans<<endl; return 0; }View Code
G题
签到题
#include<bits/stdc++.h> using namespace std; #define LL long long int main(){ LL x,y; LL sum=1; scanf("%lld %lld\n",&x,&y); while(sum<=x) { sum*=2; } sum--; printf("2\n"); printf("%lld %lld\n",sum^x,sum^y); return 0; }View Code
L题
数位dp,观察求的是1的个数,而一个进位会影响到前面连续的1,因此我们要保留连续1的奇偶性,并且要保留全部1的奇偶性,但是这样还是没法,数据量依旧大
这个时候我们发发现因为m很小,所以只需要后7位就能记录所有相加的可能性,而只产生一个进位,因此对于后7位暴力计算,而只保留第七位往前的信息,这样复杂度就能过了
这样只会计算64*128*2*2*2左右的状态
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,int> pll; const int N=1e6+10; const ll mod=998244353; ll f[65][128][2][2][2]; ll m,n; int s[100],cnt; int a[N]; int cal(int sta,int pre,int tot){ int res=1; for(int i=0;i<m;i++){ if(sta+i<128){ res&=((__builtin_parity(sta+i)^tot)==a[i]); } else{ res&=((__builtin_parity(sta+i)^pre^tot)==a[i]); } } return res; } ll dfs(int u,int sta,int sign,int pre,int tot){ if(u==-1) return cal(sta,pre,tot); auto &x=f[u][sta][sign][pre][tot]; if(x!=-1) return x; int up=1; if(sign) up=s[u]; ll res=0; for(int i=0;i<=up;i++){ if(u>6){ res+=dfs(u-1,(sta*2+i)&127,sign&&(i==up),i&(!pre),tot^i); } else{ res+=dfs(u-1,(sta*2+i)&127,sign&&(i==up),pre,tot); } } x=res; return x; } ll solve(ll n){ cnt=0; memset(f,-1,sizeof f); if(n==0){ s[cnt++]=0; } while(n){ s[cnt++]=n&1; n/=2; } return dfs(cnt-1,0,1,0,0); } int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ cin>>m>>n; for(int i=0;i<m;i++){ cin>>a[i]; } cout<<solve(n)<<endl; } return 0; }View Code
M题
签到题
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=1e6+10; int main(){ ios::sync_with_stdio(false); int n,k; cin>>n>>k; if(n<=k){ cout<<2<<endl; return 0; } n*=2; if(n%k){ cout<<n/k+1<<endl; } else{ cout<<n/k<<endl; } return 0; }View Code
标签:typedef,const,int,题解,ll,long,2020ICPC,include,济南 来源: https://www.cnblogs.com/ctyakwf/p/14355105.html