赞
踩
Simple Set Problem 尺取,双指针,排序
Data Generation 概率,矩阵快速幂
PSO 期望,签到
Guess 推式子,Pollard-Rho筛素数获得全部因子
Kong Ming Qi 构造
Circuit 最短路计数,弗洛伊德
a-b Problem 贪心,签到
首先将全部数字加入集合,数字记录所属集合,从小到大移动左指针,而后右指针在原来基础上向右扩展至第一个满足的即可。取一个最小值
- # include<bits/stdc++.h>
- using namespace std;
- typedef long long int ll;
- struct node
- {
- int val,id;
- };
- struct node s[1000000+10];
- int cnt[1000000+10];
- bool cmp(struct node &x,struct node&y)
- {
- return x.val<y.val;
- }
- int main()
- {
- cin.tie(0);
- ios::sync_with_stdio(0);
- int t;
- cin>>t;
- while(t--)
- {
- int n;
- cin>>n;
- for(int i=1;i<=n;i++)
- {
- cnt[i]=0;
- }
- int len=0;
- for(int i=1;i<=n;i++)
- {
- int x;
- cin>>x;
- for(int j=1;j<=x;j++)
- {
- len++;
- cin>>s[len].val;
- s[len].id=i;
- }
- }
- sort(s+1,s+1+len,cmp);
- int ans=2e9+10;
- int pos=0,nowcnt=0;
- for(int i=1;i<=len;i++)
- {
- if(i>=2)
- {
- cnt[s[i-1].id]--;
- if(cnt[s[i-1].id]==0)
- nowcnt--;
- }
- while(pos<=len&&nowcnt<n)
- {
- pos++;
- cnt[s[pos].id]++;
- if(cnt[s[pos].id]==1)
- nowcnt++;
- }
-
- if(nowcnt==n&&pos<=len)
- {
- ans=min(ans,s[pos].val-s[i].val);
- }
- }
- cout<<ans<<'\n';
- }
- return 0;
- }
最终答案就是由于每个位置匹配成功的贡献是1,所以最终答案就是n-每个匹配成功的期望。
而每个位置还是相互独立的,所以可以看成n*p[0] 其中p[0]是m次交换之后次成功的期望。
当第i-1次0在自己的位置上时,p[i-1] * ( 1 + (n-1)^2 ) / ( n^2 ),即n^2种交换,只有[0,0]交换,和没有0的交换才能保证0仍然在原位置不懂。
当第i-1次0不在自己的位置上时,( 1-p[i-1] ) * ( 2/(n^2) )
二者综合,可以得出p[i]=(n-2)/n * p[i-1] + 2 / (n^2)
可以用矩阵快速幂解决,但n,m的范围很大,注意对n取模,防止相乘直接爆ll
#include <bits/stdc++.h> using namespace std; typedef long long int ll; # define mod 998244353 ll base[2][2],res[2][2]; void mulans() { ll temp[2][2]; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { temp[i][j]=0; } } for(int k=0;k<2;k++) { for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { temp[i][j]=(temp[i][j]+res[i][k]*base[k][j]%mod)%mod; } } } for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { res[i][j]=temp[i][j]; } } return ; } void mulbase() { ll temp[2][2]; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { temp[i][j]=0; } } for(int k=0;k<2;k++) { for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { temp[i][j]=(temp[i][j]+base[i][k]*base[k][j]%mod)%mod; } } } for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { base[i][j]=temp[i][j]; } } return ; } void qp(ll pow) { for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { res[i][j]=0; res[i][i]=1; } } while(pow) { if(pow&1) mulans(); pow>>=1; mulbase(); } } ll qsm(ll bas,ll pow) { ll ans=1; bas%=mod; while(pow) { if(pow&1) ans=ans*bas%mod; pow>>=1; bas=bas*bas%mod; } return ans; } int main() { int t; cin>>t; while(t--) { ll n,m; scanf("%lld%lld",&n,&m); n%=mod; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { base[i][j]=0; } } ll now=((n-2)%mod+mod)%mod*qsm(n,mod-2)%mod; ll noww=2ll*qsm(n*n%mod,mod-2)%mod; base[0][0]=now; base[0][1]=base[1][1]=1; qp(m); ll ans=(res[0][0]+res[0][1]*noww%mod)%mod; ans*=n; ans%=mod; cout<<((n-ans)%mod+mod)%mod<<'\n'; } return 0; }
其实可以暴力打出前几十个数字的表,发现,只有当n时质数或者n是一个质数的幂的时候,s[n]才不是0
然后利用PR求解即可。
- #include<bits/stdc++.h>
- #define rep(i,a,b) for(int i=(a);i<=(b);i++)
- #define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
- typedef long long ll;
- using namespace std;
- const int MOD=998244353;
- ll ksm(ll a,ll b,ll p){
- ll ret=1;
- for(;b;b>>=1,a=(__int128)a*a%p)
- if(b&1)ret=(__int128)ret*a%p;
- return ret;
- }
- bool Miller_Rabin(ll p){
- if(p<2)return 0;
- if(p==2||p==3)return 1;
- ll d=p-1,r=0;
- while(!(d&1))++r,d>>=1;
- for(ll k=0;k<10;++k){
- ll a=rand()%(p-2)+2;
- ll x=ksm(a,d,p);
- if(x==1||x==p-1)continue;
- for(int i=0;i<r-1;++i){
- x=(__int128)x*x%p;
- if(x==p-1)break;
- }
- if(x!=p-1)return 0;
- }
- return 1;
- }
- int tot;
- ll decom[100];
- ll Pollard_Rho(ll x){
- ll s=0,t=0;
- ll c=(ll)rand()%(x-1)+1;
- int step=0,goal=1;
- ll val=1;
- for(goal=1;;goal<<=1,s=t,val=1){
- for(step=1;step<=goal;step++){
- t=((__int128)t*t+c)%x;
- val=(__int128)val*abs(t-s)%x;
- if(step%127==0){
- ll d=__gcd(val,x);
- if(d>1)return d;
- }
- }
- ll d=__gcd(val,x);
- if(d>1)return d;
- }
- }
- void solve(ll x){
- if(x<2)return;
- if(Miller_Rabin(x)){
- decom[++tot]=x;
- return;
- }
- ll p=x;
- while(p==x)p=Pollard_Rho(x);
- solve(x/p);solve(p);
- }
- # define mod 998244353
- int main(){
- fastio;
- srand(time(0));
- int T;cin>>T;
- while(T--){
- tot=0;
- ll n;cin>>n;
- assert(1<=n&&n<=(ll)(1e18));
- solve(n);
- sort(decom+1,decom+tot+1);
- tot=unique(decom+1,decom+tot+1)-(decom+1);
-
- if(tot==1)
- {
- cout<<decom[1]%mod<<" ";
- }
- else
- {
- cout<<1<<" ";
- }
- }
- return 0;
- }
首先有一个构造方案,图中黑点可以消去白点三个,而自己保持不变。根据这一构造,在n>=3的时候,如果m>=3,可以先利用左侧消去将m消三列,留下最后三行的后三列没被消去,利用右侧方案,消去。最终会变成一个n<=3,m<=3的情况
首先n=1||m=1的时候,是对应行列个数除以2向上取整。
n<=3m<=3的时候可以打表出来
#include <bits/stdc++.h> using namespace std; typedef long long int ll; int nx[4]={0,0,-1,1}; int ny[4]={1,-1,0,0}; int a[10][10],n,m; bool check(int x,int y) { return x>=0&&x<=n+1&&y>=0&&y<=m+1; } int ans=1e9; int all; void work() { int flag=0; if(ans==1) return ; for(int i=0;i<=n+1;i++) { for(int j=0;j<=m+1;j++) { if(a[i][j]) { for(int k=0;k<4;k++) { int xx=i+nx[k]; int yy=j+ny[k]; if(check(xx,yy)&&a[xx][yy]) { int xxx=xx+nx[k]; int yyy=yy+ny[k]; if(check(xxx,yyy)&&!a[xxx][yyy]) { a[i][j]=0; a[xx][yy]=0; a[xxx][yyy]=1; work(); a[i][j]=1; a[xx][yy]=1; a[xxx][yyy]=0; flag=1; } } } } } } if(flag==0) { int nowcnt=0; for(int i=0;i<=n+1;i++) { for(int j=0;j<=m+1;j++) { nowcnt+=(a[i][j]); } } if(nowcnt<ans) { //cout<<nowcnt<<'\n'; ans=nowcnt; } } } int pre[10][10]; int main() { pre[1][1]=1; pre[1][2]=1; pre[1][3]=2; pre[1][4]=2; pre[2][1]=1; pre[3][1]=2; pre[4][1]=2; pre[2][2]=1; pre[2][3]=2; pre[2][4]=1; pre[3][2]=2; pre[3][3]=2; pre[3][4]=2; pre[4][2]=1; pre[4][3]=2; pre[4][4]=1; int t; cin>>t; while(t--) { int x,y; scanf("%d%d",&x,&y); if(x>y) swap(x,y); if(x==1) { cout<<(y+1)/2<<'\n'; } else { if(x<=4&&y<=4) { cout<<pre[x][y]<<'\n'; } else { x%=3; y%=3; if(x<=0) x+=3; if(y<=0) y+=3; cout<<pre[x][y]<<'\n'; } } } return 0; }
有向图计环,在弗洛伊德的时候,转移点k从1枚举到n。考虑对每个环,记录包含[1,1],[1,2],[1,3]...[1,n]的全部环,对于一个包含[1,k]的环,要想不重复的记录,需要以k为起点,这样,包含[1,2]的以2为起点的环,和包含[1,3]以3为起点的环。一定不会重复。又比如,[1,7]的环中,有[4,6],[1,3]。。各种,而[4,6]的环,在[1,6]的时候,已经被以6为起点的记录。
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long int ll;
- ll dis[510][510],cnt[510][510],inf=1e15,edge[510][510];
- # define mod 998244353
- int main()
- {
- cin.tie(0);
- ios::sync_with_stdio(0);
- int t;
- cin>>t;
- while(t--)
- {
- int n,m;
- cin>>n>>m;
- for(int i=1; i<=n; i++)
- {
- for(int j=1; j<=n; j++)
- {
- dis[i][j]=inf;
- dis[i][i]=0;
- cnt[i][j]=0;
- edge[i][j]=0;
- }
- }
- while(m--)
- {
- int x,y;
- ll val;
- cin>>x>>y>>val;
- dis[x][y]=min(dis[x][y],val);
- edge[x][y]=val;
- cnt[x][y]=1;
- }
- ll minn=1e18,ans=0;
- for(int k=1; k<=n; k++)
- {
- for(int i=1; i<=n; i++)
- {
- for(int j=1; j<=n; j++)
- {
- if(dis[i][j]==dis[i][k]+dis[k][j])
- {
- cnt[i][j]=(cnt[i][j]+cnt[i][k]*cnt[k][j]%mod)%mod;
- }
- else if(dis[i][j]>dis[i][k]+dis[k][j])
- {
- dis[i][j]=dis[i][k]+dis[k][j];
- cnt[i][j]=cnt[i][k]*cnt[k][j]%mod;
- }
-
- }
- }
- for(int i=1; i<k; i++)
- {
- if(edge[k][i])
- {
- if(edge[k][i]+dis[i][k]<minn)
- {
- minn=edge[k][i]+dis[i][k];
- ans=cnt[i][k];
- }
- else if(edge[k][i]+dis[i][k]==minn)
- {
- ans+=cnt[i][k];
- ans%=mod;
- }
- }
- }
- }
- if(minn>=inf)
- {
- cout<<-1<<" "<<-1<<'\n';
- continue;
- }
- cout<<minn<<" "<<ans<<'\n';
- }
-
- return 0;
- }
按照A+B排序的原理是,A+B如果大,要么可以让自己加的分多,要么可以避免对面加更多的分。
- # include<bits/stdc++.h>
- using namespace std;
- typedef long long int ll;
- struct node
- {
- int a,b,c;
- };
- struct node s[100000+10];
- bool cmp(struct node &x, struct node &y)
- {
- return x.c>y.c;
- }
- int main()
- {
- cin.tie(0);
- ios::sync_with_stdio(0);
- int t;
- cin>>t;
- while(t--)
- {
- int n;
- cin>>n;
- for(int i=1;i<=n;i++)
- {
- cin>>s[i].a>>s[i].b;
- s[i].c=s[i].a+s[i].b;
- }
- sort(s+1,s+1+n,cmp);
- ll sum1=0,sum2=0;
- for(int i=1;i<=n;i++)
- {
- if(i%2)
- {
- sum1+=s[i].a;
- }
- else
- {
- sum2+=s[i].b;
- }
- }
-
- cout<<sum1-sum2<<'\n';
- }
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。