多校冲刺 noip 11.04
多校冲刺 noip 11.04
今天挂大分!!我不嘚。。。
所以我啥时候可以把情况考虑完全啊!!
啥时候可以随出来把我程序卡掉的数据啊!!
T1 谜之阶乘
这题随便做就能切,真的随便做......
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--)
const int N=1e6+5;
int T,n,mx=1e18;
int cx[22][N],dy[22][N];
int cnt[23],c,ans[30][2];
signed main(){
freopen("factorial.in","r",stdin);
freopen("factorial.out","w",stdout);
// cout<<(sizeof(cx)*3>>20)<<endl;
fo(i,4,1000001){
int now=i*(i-1);
fu(j,i-2,2){
if(now>mx/j)break;
now*=j;
cx[i-j+1][++cnt[i-j+1]]=now;
dy[i-j+1][cnt[i-j+1]]=i;
}
}
scanf("%lld",&T);
while(T--){
scanf("%lld",&n);
if(n==1){printf("-1\n");continue;}
c=1;ans[1][0]=n;ans[1][1]=n-1;
int sq=sqrt(n);if(n!=2&&sq*(sq+1)==n)ans[++c][0]=sq+1,ans[c][1]=sq-1;
fo(i,3,20){
int pos=lower_bound(cx[i]+1,cx[i]+cnt[i]+1,n)-cx[i];
if(cx[i][pos]==n)ans[++c][0]=dy[i][pos],ans[c][1]=dy[i][pos]-i;
}
printf("%lld\n",c);
fu(i,c,1)printf("%lld %lld\n",ans[i][0],ans[i][1]);
}
return 0;
}
T2 子集
这个我找的规律好像不太好形容,所以看代码吧
考场上因为不会用官方给的\(checker\),于是自己写了一个.....
checker
#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--)
const int N=1e6+5;
int T,n,k;
int vis[N];
signed main(){
FILE *f1=fopen("subset.in","r");
FILE *f2=fopen("subset.out","r");
FILE *f3=fopen("b.ans","w");
fscanf(f1,"%lld",&T);
fo(t,1,T){
fscanf(f1,"%lld%lld",&n,&k);
fo(i,1,n)vis[i]=false;
char s[10];fscanf(f2,"%s",s+1);
if(s[1]=='N')continue;
fo(i,1,k){
int sum=0;
fo(j,1,n/k){
int x;fscanf(f2,"%lld",&x);
if(vis[x]||x>n){fprintf(f3,"WA on test %lld ",t);return 0;}
sum+=x;vis[x]=true;
}
if(sum!=(n*(n+1))/2/k){fprintf(f3,"WA on test %lld ",t);return 0;}
}
}
fprintf(f3,"AC");
return 0;
}
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--)
const int N=1e6+5;
int T,n,k;
int odd[N][3];
void get_odd(int x){
int mx=x*3;
odd[1][0]=1;
odd[1][1]=(mx>>1)+1;
odd[1][2]=mx;
fo(i,2,x){
if(odd[i-1][1]+1==odd[i-1][2]){
odd[i][0]=odd[i-1][0]+1;
odd[i][1]=(((mx>>1)-i+1)>>1)+odd[i][0];
odd[i][2]=mx-1;
continue;
}
odd[i][0]=odd[i-1][0]+1;
odd[i][1]=odd[i-1][1]+1;
odd[i][2]=odd[i-1][2]-2;
}
}
signed main(){
freopen("subset.in","r",stdin);
freopen("subset.out","w",stdout);
scanf("%lld",&T);
while(T--){
scanf("%lld%lld",&n,&k);
if(n==1&&k==1){printf("Yes\n1\n");continue;}
int sum=n*(n+1)/2,num;
if(sum%k!=0||sum/k<n){printf("No\n");continue;}
printf("Yes\n");num=n/k;
if(num&1){
get_odd(k);
int s=k*3+1,t=n;
fo(i,1,k){
printf("%lld %lld %lld ",odd[i][0],odd[i][1],odd[i][2]);
fo(i,4,num){
if(i&1)printf("%lld ",s),s++;
else printf("%lld ",t),t--;
}
printf("\n");
}
}
else {
int s=1,t=n;
fo(i,1,k){
fo(i,1,num){
if(i&1)printf("%lld ",s),s++;
else printf("%lld ",t),t--;
}
printf("\n");
}
}
}
return 0;
}
T3 混凝土粉末
这个题应该是个套路吧,只是我没有见过,然后智商有点低,就没有想出来
首先我们知道,如果某一次放沙子对某一次询问有贡献
我们需要保证两个条件:
第一个是空间上,修改必须覆盖询问
第二个是时间上,修改必须在询问前面
我们发现这个题意可以转化为,询问\(x\)位置上高度大于\(y\)的最早时间
这样转化完之后,很容易发现可以用二分,但是需要下面的维护
发现二分需要区间可加性,但是我们所说的空间是区间不可加的
所以我们扫描空间,用线段树维护时间
我们对于每一个询问,在基岩轴的左端点加上高度,右端点减去高度
每一个询问,我们也可以将它放到基岩轴上去,可以直接在线段树上二分
线段树维护的是时间轴
我们直接扫描这个基岩轴
遇到需要加的就在线段树上对应的时间处加上,减去一样
查询直接在询问的时间左边二分就好了
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--)
const int N=1e6+5;
int n,q;
struct XDS{
#define ls x<<1
#define rs x<<1|1
int sum[N*4],res,mx;
void pushup(int x){
sum[x]=sum[ls]+sum[rs];
return ;
}
void ins(int x,int l,int r,int pos,int v){
if(l==r)return sum[x]+=v,void();
int mid=l+r>>1;
if(pos<=mid)ins(ls,l,mid,pos,v);
else ins(rs,mid+1,r,pos,v);
pushup(x);return ;
}
void query(int x,int l,int r,int qr){
if(~res||l>qr)return ;
if(r<=qr){
if(l==r){
if(sum[x]>=mx)res=l;
else mx-=sum[x];
return ;
}
int mid=l+r>>1;
if(sum[ls]<mx)mx-=sum[ls],query(rs,mid+1,r,qr);
else query(ls,l,mid,qr);
return ;
}
int mid=l+r>>1;
query(ls,l,mid,qr);
query(rs,mid+1,r,qr);
return ;
}
#undef ls
#undef rs
}xds;
vector<pair<int,int> > add[N],del[N],qry[N];
int ans[N];
signed main(){
freopen("concrete.in","r",stdin);
freopen("concrete.out","w",stdout);
scanf("%lld%lld",&n,&q);
for(int i=1,tp,l,r,h;i<=q;i++){
scanf("%lld%lld%lld",&tp,&l,&r);
if(tp==1){ans[i]=-1;
scanf("%lld",&h);
add[l].push_back(make_pair(h,i));
del[r+1].push_back(make_pair(h,i));
}
else {
qry[l].push_back(make_pair(r,i));
}
}
fo(i,1,n){
for(auto j:add[i])xds.ins(1,1,q,j.second,j.first);
for(auto j:del[i])xds.ins(1,1,q,j.second,-j.first);
for(auto j:qry[i]){
xds.res=-1;xds.mx=j.first;
xds.query(1,1,q,j.second);
ans[j.second]=xds.res==-1?0:xds.res;
}
}
fo(i,1,q)if(ans[i]!=-1)printf("%lld\n",ans[i]);
}
T4 排水系统
考场上干傻了,没看见只有一条坏了,直接转移还有\(36pts\)
所以我们可以维护出来每一个位置的期望变化值
因为只有一条边是坏掉的,所以我们就可以先按照没有变化的推一遍
这时候求出来每一个点的变化值
再推一遍,将变化值下放
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--)
const int N=2e5+5;
const int M=5e5+5;
const int mod=998244353;
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 n,m,r,k;
int to[M],nxt[M],a[M],head[N],rp;
void add_edg(int x,int y,int z){
to[++rp]=y;
a[rp]=z;
nxt[rp]=head[x];
head[x]=rp;
}
int sum[N],cd[N],rd[N],du[N],all,inv;
int dp[N];
queue<int> q;
signed main(){
freopen("water.in","r",stdin);
freopen("water.out","w",stdout);
scanf("%lld%lld%lld%lld",&n,&m,&r,&k);
fo(i,1,k){
int x,y,z;scanf("%lld%lld%lld",&x,&y,&z);
add_edg(x,y,z);all=(all+z)%mod;
cd[x]++;rd[y]++;du[y]++;
}
inv=ksm(all,mod-2);
fo(i,1,m){sum[i]=dp[i]=1;q.push(i);}
while(!q.empty()){
int x=q.front();q.pop();
dp[x]=(dp[x]-sum[x]+mod)%mod;
int no=0,ys=0;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
int now=sum[x]*ksm(cd[x]-1,mod-2)%mod*a[i]%mod*inv%mod;
ys=(ys+now)%mod;no=(no+a[i])%mod;
dp[y]=(dp[y]-now+mod)%mod;
}
no=(all-no+mod)%mod*inv%mod;
ys=(ys+no*sum[x]%mod*ksm(cd[x],mod-2)%mod)%mod;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];rd[y]--;
dp[y]=(dp[y]+ys)%mod;
sum[y]=(sum[y]+sum[x]*ksm(cd[x],mod-2))%mod;
if(!rd[y])q.push(y);
}
}
//fo(i,1,n)cout<<sum[i]<<" "<<dp[i]<<endl;
fo(i,1,m)q.push(i);
while(!q.empty()){
int x=q.front();q.pop();
for(int i=head[x];i;i=nxt[i]){
int y=to[i];du[y]--;
dp[y]=(dp[y]+dp[x]*ksm(cd[x],mod-2))%mod;
if(!du[y])q.push(y);
}
}
//fo(i,1,n)cout<<sum[i]<<" "<<dp[i]<<endl;
fo(i,n-r+1,n)printf("%lld ",(dp[i]+sum[i])%mod);
return 0;
}
QQ:2953174821

浙公网安备 33010602011771号