省选模拟37
连续垫底第五场,希望自己对垫底没有什么感觉,但是还是很伤心,为啥自己突然这么菜
成绩的上下波动一直很厉害,不知道该咋办......
上来看第一题,发现计数不是记少了就是记重了,两个半小时之后弃掉了
然后看第二题,发现只会暴力分,抱着试试看的想法搞了一下逆序对个数发现不对就走了
第三题,一点思路都没有...
T1 小 F 与游戏
也不用说了,我是打表找规律过的...%%%APJifengc
AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=5e5+5;
const int inf=0x3f3f3f3f3f3f3f3f;
int n,k,mod,ans;
int ksm(int x,int y){
int ret=1;
while(y){
if(y&1)ret=ret*x%mod;
x=x*x%mod;y>>=1;
}return ret;
}
int jc[N*2],inv[N*2];
int C(int x,int y){return jc[x]*inv[y]%mod*inv[x-y]%mod;}
signed main(){
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
n=read();k=read();mod=read();
jc[0]=1;fo(i,1,2*n)jc[i]=jc[i-1]*i%mod;
inv[0]=1;inv[2*n]=ksm(jc[2*n],mod-2);
fu(i,2*n-1,1)inv[i]=inv[i+1]*(i+1)%mod;
if(k==1){printf("%lld\n",ksm(2,n-2));}
else if(k==n){printf("%lld\n",C(2*n-2,n-1)*ksm(n,mod-2)%mod);}
else {printf("%lld\n",ksm(2,n-k-1)*(C(n+k-2,n-1)-C(n+k-2,n)+mod)%mod);}
return 0;
}
T2 小 Z 与函数
发现交换的是顺序对个数,但是前面的重复数字只计算一次
那么剩下的任务就是看哪些点是需要交换的
这个地方我搞了好久好久,要理解一个思想,就是问题拆分化,如果发现一个问题的两个部分没有关系那么就可以分开计算了
对于每一个位置单独考虑,处理当前位置的时候,这个位置的数是前缀最小值
那么只要这个数后面还有一个比他大的数,那这个位置就需要交换
如果有相同的数,那么我们就接着上一个找到的位置继续向后找就行了
这个是保证一共有至少i个数大于当前这个数,这样就必须向后移动了
AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=2e5+5;
const int inf=0x3f3f3f3f3f3f3f3f;
int T,n,a[N],ans,res;
bool vis[N];
struct BIT{
int tr[N];
void ins(int x,int v){
for(int i=x;i<=n;i+=(i&-i))tr[i]+=v;
}
int query(int x){
int ret=0;
for(int i=x;i;i-=(i&-i))ret+=tr[i];
return ret;
}
int qry(int l,int r){
return query(r)-query(l-1);
}
}bit,bic;
int sta[N],top,len[N];
int mn[N],las[N],ps[N],pos[N];
struct XDS{
#define ls x<<1
#define rs x<<1|1
int mx[N*4];
void pushup(int x){
mx[x]=max(mx[ls],mx[rs]);
return ;
}
void build(int x,int l,int r){
if(l==r)return mx[x]=a[l],void();
int mid=l+r>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(x);return ;
}
int query(int x,int l,int r,int ql,int v){
if(ql>n)return n+1;
if(ql<=l){
if(mx[x]<=v)return r+1;
if(l==r)return r;
int mid=l+r>>1;
if(mx[ls]<=v)return query(rs,mid+1,r,ql,v);
else return query(ls,l,mid,ql,v);
}
int mid=l+r>>1,ret=0;
if(ql<=mid)ret=query(ls,l,mid,ql,v);
if(!ret||ret==mid+1)ret=query(rs,mid+1,r,ql,v);
return ret;
}
#undef ls
#undef rs
}xds;
signed main(){
freopen("function.in","r",stdin);
freopen("function.out","w",stdout);
T=read();mn[0]=inf;
while(T--){
memset(vis,false,sizeof(vis));
memset(bit.tr,0,sizeof(bit.tr));
memset(bic.tr,0,sizeof(bic.tr));
memset(pos,0,sizeof(pos));
n=read();ans=0;res=0;
fo(i,1,n){
a[i]=read();
mn[i]=min(mn[i-1],a[i]);
if(mn[i-1]==a[i])las[i]=ps[i-1],ps[i]=i;
if(mn[i-1]>a[i])las[i]=0,ps[i]=i;
if(mn[i-1]<a[i])ps[i]=ps[i-1];
}
xds.build(1,1,n);
// cerr<<"ZZ"<<endl;
fo(i,1,n){
// cerr<<i<<" "<<ps[i]<<" "<<las[ps[i]]<<endl;
if(mn[i]==mn[i-1])pos[i]=xds.query(1,1,n,max(i,pos[i-1])+1,mn[i]);
else pos[i]=xds.query(1,1,n,i+1,mn[i]);
if(pos[i]<=n)bic.ins(pos[i],1);
// cerr<<pos[i]<<endl;
}
// cerr<<endl;
// cerr<<"ZZ"<<endl;
fo(i,1,n){
ans+=bit.qry(1,a[i]-1);
printf("%lld ",ans+bic.query(i));
if(!vis[a[i]])bit.ins(a[i],1);
vis[a[i]]=true;
}
printf("\n");
}
return 0;
}
T3 小 W 与骑士
所以这个题好像挺简单的???
首先平行的情况,我们直接建边缩点,当然我没有这么写(因为数据水
不平行就直接解方程,然后容斥,设\(f_i\)表示走到的第一个障碍点是i的方案数,因为走路是无环的
所以减去走过来的方案数,一路dfs就行了
AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=505;
const int mod=1e9+7;
int ksm(int x,int y){
int ret=1;
while(y){
if(y&1)ret=ret*x%mod;
x=x*x%mod;y>>=1;
}return ret;
}
int T,n,x,y,ax,ay,bx,by;
struct node{
int x,y;
bool operator < (node a)const{
if(x!=a.x)return x<a.x;
return y<a.y;
}
bool operator != (node a)const{
return x!=a.x||y!=a.y;
}
}no[N];
bool isn[N];
int dp[N*2];
void spj1(){
if(x*ay!=y*ax)return printf("0\n"),void();
if(ax*bx<0)return printf("-1\n"),void();
if(ax<0)return printf("0\n"),void();
memset(isn,false,sizeof(isn));
fo(i,1,n)if(no[i].x>=0&&no[i].x*y==no[i].y*x){
isn[no[i].x]=true;
}dp[0]=1;
if(ax){
fo(i,1,x){
dp[i]=0;if(isn[i])continue;
if(i>=ax)dp[i]=(dp[i]+dp[i-ax])%mod;
if(i>=bx&&ax!=bx)dp[i]=(dp[i]+dp[i-bx])%mod;
}
printf("%lld\n",dp[x]);return ;
}
if(ay){
fo(i,1,y){
dp[i]=0;if(isn[i])continue;
if(i>=ay)dp[i]=(dp[i]+dp[i-ay])%mod;
if(i>=by&&ay!=by)dp[i]=(dp[i]+dp[i-by])%mod;
}
printf("%lld\n",dp[y]);return ;
}
}
int jc[N*N*10],inv[N*N*10];
int C(int a,int b){return jc[a]*inv[b]%mod*inv[a-b]%mod;}
int wok(int x,int y){
int k,b;
if((bx*ay-by*ax)==0)return 0;
b=(x*ay-y*ax)/(bx*ay-by*ax);
if(b*(bx*ay-by*ax)!=(x*ay-y*ax))return 0;
if(b<0)return 0;
if(ax){
k=(x-b*bx)/ax;
if(k*ax!=x-b*bx)return 0;
if(k<0)return 0;
}
else {
k=(y-b*by)/ay;
if(k*ay!=y-b*by)return 0;
if(k<0)return 0;
}
return C(k+b,b);
}
int dfs(int a){
if(~dp[a])return dp[a];
int ret=wok(no[a].x,no[a].y);
if(!ret)return dp[a]=0;
fo(i,1,n)if(i!=a&&no[i]!=no[i-1]){
int sm=wok(no[a].x-no[i].x,no[a].y-no[i].y);
if(!sm)continue;
ret=(ret-sm*dfs(i)%mod+mod)%mod;
}
return dp[a]=ret;
}
void spj2(){
memset(dp,-1,sizeof(dp));
no[0].x=x;no[0].y=y;
printf("%lld\n",dfs(0));
}
signed main(){
freopen("knight.in","r",stdin);
freopen("knight.out","w",stdout);
T=read();
jc[0]=1;fo(i,1,2500000)jc[i]=jc[i-1]*i%mod;
inv[0]=1;inv[2500000]=ksm(jc[2500000],mod-2);
fu(i,2499999,1)inv[i]=inv[i+1]*(i+1)%mod;
while(T--){
x=read();y=read();n=read();
ax=read();ay=read();bx=read();by=read();
fo(i,1,n)no[i].x=read(),no[i].y=read();
sort(no+1,no+n+1);
if(x<0){
ax=-ax;bx=-bx;x=-x;
fo(i,1,n)no[i].x=-no[i].x;
}
if(y<0){
ay=-ay;by=-by;y=-y;
fo(i,1,n)no[i].y=-no[i].y;
}
if(ax*by==bx*ay||(!ax&&!ay)||(!bx&&!by))spj1();
else spj2();
}
return 0;
}
QQ:2953174821