noip模拟69[挂分大法好]
noip模拟69 solutions
考得非常拉,拉爆了!!!
关于我挂分这个事,我不知道我为什么已经两次没有看全题了
这次本来输出两个数,我只输出了第二个,挂掉50
但是我到极限也只有\(180pts\),所以我还是菜了
T1 石子游戏
不会,我只有\(50pts\),直接超级大暴力\(SG\)函数
AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#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=5e5+5;
int n,a[N],sg[N];
bool vis[N];
int na[N],cnt;
signed main(){
#ifdef oj
freopen("stone.in","r",stdin);
freopen("stone.out","w",stdout);
#endif
scanf("%d",&n);
fo(i,1,n){
scanf("%d",&a[i]);
if(vis[a[i]])vis[a[i]]=false;
else vis[a[i]]=true;
}
fo(i,1,n)if(vis[i])na[++cnt]=i;
fo(k,1,n){
int ans=0;
fo(i,1,cnt)ans^=na[i]%(k+1);
if(ans)printf("Alice ");
else printf("Bob ");
}
}
好啦好啦我会\(100pts\)的做法了
首先我们理解这个dp,对于\(-i\)这个限制来说,我想让\(j\)这一位是1,它加上\(1<<j+1\)之后的这一位 仍然是合法的
那么我们考虑\(i~i+(1<<j+1)-1\)这个区间之内的,这个直接用我们预处理出来的\(c\)数组就好了
考虑如何利用这个数组得到答案,我们枚举\(x\)的大小
每次去遍历每一位,这是一个\(log\),枚举每一个块,这应该是\(ln\),反正都差不多
我们先用\(dp\)数组加减一下,在处理一下散块,为什么会出现散块,因为处理的时候是一块一块处理的
AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fxt(i,x,y) for(int i=(x);i<=(y);i++)
#define pyt(i,x,y) for(int i=(x);i>=(y);i--)
const int N=1e6+5;
int n,a[N],f[N<<2][22],c[N<<2],mx;
signed main(){
freopen("stone.in","r",stdin);
freopen("stone.out","w",stdout);
scanf("%lld",&n);
fxt(i,1,n){
scanf("%lld",&a[i]);
c[a[i]]++;
mx=max(mx,a[i]);
}
fxt(i,1,N<<1)c[i]+=c[i-1];
pyt(i,mx,0)fxt(j,0,19)f[i][j]=f[i+(1<<j+1)][j]+c[i+(1<<j+1)-1]-c[i+(1<<j)-1];
fxt(x,1,n){
int k=n/(x+1);
bool flag=false;
fxt(i,0,19){
int res=0;
fxt(j,0,k){
int l=j*(x+1),r=(j+1)*(x+1)-1;
int num=(r-l+1)/(1<<i+1);
res+=(num?f[l][i]-f[l+num*(1<<i+1)][i]:0)+max(0ll,c[r]-c[l+num*(1<<i+1)+(1<<i)-1]);
}
if(res&1){flag=true;break;}
}
if(flag)printf("Alice ");
else printf("Bob ");
}
}
T2 大鱼吃小鱼
这个会是会了,但是还没有打出来
不打啦不打啦!!!!
好像是差不多了\(88pts\)但是有点抵触这个题了,不想调了
88pts
#include<bits/stdc++.h>
using namespace std;
namespace FXT{
#define oj
#define int long long
#define fxt(i,x,y) for(int i=(x);i<=(y);i++)
#define pyt(i,x,y) for(int i=(x);i>=(y);i--)
const int N=1e6+5;
const int inf=0x7fffffffffffffff;
int n,q,sca[N],qus[N][3];
int lsh[N*2],lh;
multiset<int> st;
struct XDS{
#define ls x<<1
#define rs x<<1|1
int sum[N*8],cnt[N*8];
int bin[N*8][5],tot,vis[N*8];
int pos,sm;
void bi(int x,int l,int r){
if(vis[x])return ;
bin[++tot][0]=x;
bin[tot][1]=sum[x];
bin[tot][2]=cnt[x];
bin[tot][3]=l;
bin[tot][4]=r;
sum[x]=cnt[x]=0;
vis[x]=true;
}
void hf(int x,int l,int r,int ql,int qr,int sm,int ct){
if(ql<=l&&r<=qr)return sum[x]=sm,cnt[x]=ct,void();
int mid=l+r>>1;
if(ql<=mid)hf(ls,l,mid,ql,qr,sm,ct);
else hf(rs,mid+1,r,ql,qr,sm,ct);
pushup(x);return ;
}
void hy(){
pyt(i,tot,1){
hf(1,1,lh,bin[i][3],bin[i][4],bin[i][1],bin[i][2]);
//sum[bin[i][0]]=bin[i][1];
//cnt[bin[i][0]]=bin[i][2];
vis[bin[i][0]]=false;
}
tot=0;
return ;
}
void pushup(int x){
cnt[x]=cnt[ls]+cnt[rs];
sum[x]=sum[ls]+sum[rs];
return ;
}
void ins(int x,int l,int r,int pos,int v){
if(l==r){
sum[x]+=v*lsh[pos];cnt[x]+=v;
//cout<<"ins "<<x<<" "<<l<<" "<<r<<" "<<pos<<" "<<v<<endl;
return ;
}
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(pos||l>qr)return ;
int mid=l+r>>1;
if(r<=qr){
if(l==r){
if(sum[x]>=sm){
pos=l;
//if(sm>=0)cout<<"xds"<<" "<<l<<" "<<r<<" "<<qr<<" "<<sum[x]<<" "<<sm<<endl;
}
else sm-=sum[x];
return ;
}
if(sum[rs]>=sm)query(rs,mid+1,r,qr);
else sm-=sum[rs],query(ls,l,mid,qr);
return ;
}
query(rs,mid+1,r,qr);
query(ls,l,mid,qr);
return ;
}
int Sum(int x,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return sum[x];
int mid=l+r>>1,ret=0;
if(ql<=mid)ret+=Sum(ls,l,mid,ql,qr);
if(qr>mid)ret+=Sum(rs,mid+1,r,ql,qr);
return ret;
}
int Cnt(int x,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return cnt[x];
int mid=l+r>>1,ret=0;
if(ql<=mid)ret+=Cnt(ls,l,mid,ql,qr);
if(qr>mid)ret+=Cnt(rs,mid+1,r,ql,qr);
return ret;
}
void del(int x,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return bi(x,l,r),void();
int mid=l+r>>1;
if(ql<=mid)del(ls,l,mid,ql,qr);
if(qr>mid)del(rs,mid+1,r,ql,qr);
pushup(x);return ;
}
#undef ls
#undef rs
}xds;
int R=1e18;
signed main(){
#ifdef oj
freopen("fish.in","r",stdin);
freopen("fish.out","w",stdout);
#endif
scanf("%lld",&n);
fxt(i,1,n)scanf("%lld",&sca[i]),lsh[++lh]=sca[i];
scanf("%lld",&q);
fxt(i,1,q){
scanf("%lld%lld",&qus[i][0],&qus[i][1]);lsh[++lh]=qus[i][1];
if(qus[i][0]==1)scanf("%lld",&qus[i][2]),lsh[++lh]=qus[i][2];
}
sort(lsh+1,lsh+lh+1);
fxt(i,1,n)sca[i]=lower_bound(lsh+1,lsh+lh+1,sca[i])-lsh,lsh[sca[i]]--;
fxt(i,1,q){
qus[i][1]=lower_bound(lsh+1,lsh+lh+1,qus[i][1])-lsh,lsh[qus[i][1]]--;
if(qus[i][0]==1)qus[i][2]=lower_bound(lsh+1,lsh+lh+1,qus[i][2])-lsh,lsh[qus[i][2]]--;
}
fxt(i,1,lh)lsh[i]++;
fxt(i,1,n)xds.ins(1,1,lh,sca[i],1),st.insert(lsh[sca[i]]);//cout<<sca[i]<<" "<<lsh[sca[i]]<<endl;
fxt(i,1,q){
if(qus[i][0]==1){
int x=lsh[qus[i][1]],y=lsh[qus[i][2]];
bool flag=false;int ans=0;
while(x<y){
xds.sm=min(st.lower_bound(x)==st.end()?inf:*st.lower_bound(x),y-1)-x+1;xds.pos=0;
int r=lower_bound(lsh+1,lsh+lh+1,x)-lsh-1;
xds.query(1,1,lh,r);//cout<<x<<" "<<xds.pos<<endl;
//if(x!=15)cout<<i<<" "<<xds.sm<<" "<<xds.pos<<" "<<r<<" "<<x<<" "<<y<<endl;
if(!xds.pos)break;
//cout<<x<<" "<<xds.pos<<" ";
x+=xds.Sum(1,1,lh,xds.pos,r);
//cout<<x<<endl;
//if(x<y&&xds.pos==1)break;
ans+=xds.Cnt(1,1,lh,xds.pos,r);
xds.del(1,1,lh,xds.pos,r);
}
xds.hy();
if(x<y)printf("-1\n");
else printf("%lld\n",ans);
}
if(qus[i][0]==2)xds.ins(1,1,lh,qus[i][1],1),st.insert(lsh[qus[i][1]]);
if(qus[i][0]==3)xds.ins(1,1,lh,qus[i][1],-1),st.erase(lsh[qus[i][1]]);
}
return 0;
}
}
signed main(){return FXT::main();}
T3 黑客 first
直接\(\mathcal{O(n^2)}\)枚举
考场上竟然没有想出来。。。。。
AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#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 mod=1e9+7;
int A,B,C,D,ans,mx;
int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
signed main(){
#ifdef oj
freopen("hacker.in","r",stdin);
freopen("hacker.out","w",stdout);
#endif
scanf("%lld%lld%lld%lld",&A,&B,&C,&D);
fo(i,1,999){
int t1=(A-1)/i;
int t2=B/i;
fo(j,1,999-i){
if(gcd(i,j)!=1)continue;
int t3=(C-1)/j;
int t4=D/j;
int tmp=min(t4,t2)-max(t1,t3);
if(tmp>0)ans=(ans+tmp%mod*(i+j))%mod;//cout<<i<<" "<<j<<" "<<tmp<<endl;
}
}
printf("%lld",ans);
}
T4 黑客 second
这个也挺好想的,就是被高精吓到了,然后就直接打部分分去了
我是枚举的之前的状态,然后只能卡常过,
\(zxb\)枚举不合法的状态转移,比我快十倍
AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#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=505;
const int p=1e8;
int n,m,k,U;
struct GJD{
int x[125];
GJD(){memset(x,0,sizeof(x));}
GJD operator + (GJD a)const{
GJD ret;int ys=0;ret.x[0]=max(x[0],a.x[0]);
fo(i,1,max(x[0],a.x[0])+1){
int tmp=x[i]+a.x[i]+ys;
if(tmp)ret.x[0]=i;
ret.x[i]=tmp%p;
ys=tmp/p;
}
return ret;
}
GJD operator * (int a)const{
GJD ret;fo(i,1,x[0])ret.x[i]=x[i]*a;
fo(i,1,x[0]+1){
if(ret.x[i])ret.x[0]=i;
ret.x[i+1]+=ret.x[i]/p;
ret.x[i]%=p;
}
return ret;
}
};
int mi[N];
GJD get(GJD a,int y){
int tmp=y/8;
GJD ret;
fo(i,1,a.x[0])ret.x[i+tmp]=a.x[i];
ret.x[0]=a.x[0]+tmp;
fo(i,1,y%8)ret=ret*10;
return ret;
}
struct node{
GJD fas,sum;
bool pd;
node(){}
node operator + (node a)const{
node ret;
ret.fas=fas+a.fas;
ret.sum=sum+a.sum;
return ret;
}
}f[N][1<<9];
void print(GJD a){
int pos=a.x[0];
printf("%d",a.x[pos]);
fu(i,pos-1,1)printf("%.8d",a.x[i]);
printf("\n");
}
vector<int> who[10];
bool vis[10],can[1<<9][10];
int ca[1<<9];
vector<int> jus[1<<9];
void dfs(int x,int t){
if(x==n+1){
f[x][t].pd=true;
f[x][t].fas.x[1]=1;
f[x][t].fas.x[0]=1;
return ;
}
node now;fo(i,1,k)if(can[t][i]){
if(!f[x+1][t|(1<<i-1)].pd)dfs(x+1,t|(1<<i-1));
f[x][t].fas=f[x][t].fas+f[x+1][t|(1<<i-1)].fas;
f[x][t].sum=f[x][t].sum+f[x+1][t|(1<<i-1)].sum;
now.sum=now.sum+f[x+1][t|(1<<i-1)].fas*i;
}
now.sum=get(now.sum,n-x);
f[x][t]=f[x][t]+now;
f[x][t].pd=true;
fo(i,0,(int)jus[t].size()-1){f[x][jus[t][i]]=f[x][t];}
return ;
}
signed main(){
#ifdef oj
freopen("hacker2.in","r",stdin);
freopen("hacker2.out","w",stdout);
#endif
scanf("%d%d%d",&n,&m,&k);
fo(i,1,m){
int x,y;scanf("%d%d",&x,&y);
who[x].push_back(y);
}
U=(1<<k)-1;
fo(s,0,U){
memset(vis,false,sizeof(vis));
fo(i,1,k)if((1<<i-1)&s)fo(j,0,(int)who[i].size()-1)vis[who[i][j]]=true;
fo(i,1,k)if(!vis[i])can[s][i]=true,ca[s]|=(1<<i-1);
}
fo(s,0,U)fo(ss,s+1,U)if(ca[s]==ca[ss]){jus[ss].push_back(s);jus[s].push_back(ss);}
dfs(1,0);
print(f[1][0].fas);
print(f[1][0].sum);
}
QQ:2953174821