10.2 上午 考试
Posted A_LEAF
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10.2 上午 考试相关的知识,希望对你有一定的参考价值。
T1
移项,然后离散,dp即可
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <ctime> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long using namespace std; const int N=200006; const int N2=500006; struct LI { int pos,val,flag; bool friend operator < (LI a,LI b) { return a.val<b.val; } }li[N2]; int con; struct son { int x,w,v[2]; bool friend operator < (son a,son b) { return a.x<b.x; } }ji[N]; int n; int f[N]; int ans; int now; void lisan() { for(int i=1;i<=n;++i) { li[++con]=(LI){i,ji[i].x-ji[i].w,0}; li[++con]=(LI){i,ji[i].x+ji[i].w,1}; } sort(li+1,li+1+con); li[0].val=-0x7fffffff; for(int i=1;i<=con;++i) { if(li[i].val==li[i-1].val) ji[li[i].pos].v[li[i].flag]=now; else ji[li[i].pos].v[li[i].flag]=++now; } } void out11() { printf("\n"); for(int i=1;i<=n;++i) printf("%d ",f[i]); printf("\n"); } int c[N2]; inline void add(int pos,int vv) { for(int i=pos;i<=now;i+=(i&(-i)) ) if(c[i]<vv) c[i]=vv; } inline int qq(int pos) { int ans=0; for(int i=pos;i>0;i-=(i&(-i)) ) if(ans<c[i]) ans=c[i]; return ans; } void dp() { int temp; for(int i=1;i<=n;++i) { temp=qq(ji[i].v[0]); f[i]=temp+1; if(ans<f[i]) ans=f[i]; add(ji[i].v[1],f[i]); } //out11(); } int main(){ //freopen("T1.in","r",stdin); //freopen("T1.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d%d",&ji[i].x,&ji[i].w); sort(ji+1,ji+1+n); lisan(); dp(); cout<<ans; }
T2
分块
#pragma GCC optimize("O2") #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <cmath> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long using namespace std; const int N=100006; int n,m; int a[N]; int fen,dui[N],L[1006],R[1006]; int mx[1006]; ll ji[1006]; void reset(int x) { mx[x]=ji[x]=0; for(int i=L[x];i<=R[x];++i) { if(mx[x]<a[i]) mx[x]=a[i]; ji[x]+=a[i]; } } void mm(int l,int r,int mod) { int q1=min(R[dui[l]],r); for(int i=l;i<=q1;++i) a[i]%=mod; reset(dui[l]); if(dui[l]!=dui[r]) { for(int i=L[dui[r]];i<=r;++i) a[i]%=mod; reset(dui[r]); } for(int i=dui[l]+1;i<dui[r];++i) { if(mx[i]<mod) continue; for(int j=L[i];j<=R[i];++j) a[j]%=mod; reset(i); } } void change(int pos,int val) { a[pos]=val; reset(dui[pos]); } ll qq(int l,int r) { ll ans=0; int q1=min(R[dui[l]],r); for(int i=l;i<=q1;++i) ans+=a[i]; if(dui[l]!=dui[r]) for(int i=L[dui[r]];i<=r;++i) ans+=a[i]; for(int i=dui[l]+1;i<dui[r];++i) ans+=ji[i]; return ans; } int main(){ freopen("T2.in","r",stdin); freopen("T2.out","w",stdout); scanf("%d%d",&n,&m); fen=(int)ceil(sqrt(n+0.5)); for(int i=1;i<=n;++i) { scanf("%d",&a[i]); dui[i]=(i-1)/fen+1; if(mx[dui[i]]<a[i]) mx[dui[i]]=a[i]; ji[dui[i]]+=a[i]; } for(int i=1;i<=dui[n];++i) { L[i]=(i-1)*fen+1; R[i]=min(n,i*fen); } int op,tin1,tin2,tin3; for(int i=1;i<=m;++i) { scanf("%d",&op); if(op==1) { scanf("%d%d",&tin1,&tin2); if(tin1>tin2) swap(tin1,tin2); printf("%lld\n",qq(tin1,tin2)); } else if(op==2) { scanf("%d%d%d",&tin1,&tin2,&tin3); if(tin1>tin2) swap(tin1,tin2); mm(tin1,tin2,tin3); } else { scanf("%d%d",&tin1,&tin2); change(tin1,tin2); } } }
T3
会炸long long INF 的SBT....
打表发现规律,然后 二分n即可
K=64,必须特判,不然炸了...
#include <cstdio> #include <cstring> #include <iostream> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long using namespace std; ll num[123]; void chu(int x) { mem(num,0); int temp=2*x; for(int i=x+1;i<=temp;++i) { int cc=0; for(int j=0;j<32;++j) if( i&(1<<j) ) ++cc; ++num[cc]; } for(int i=1;i<=32;++i) { if(num[i]==0) break; printf("%lld ",num[i]); } printf(" "); for(int i=7;i>=0;--i) printf("%d",(((1<<i)&x)?1:0) ); printf("\n"); } int main(){ freopen("biao.out","w",stdout); for(int i=1;i<=100;++i) chu(i); }
#include <cstdio> #include <cstring> #include <iostream> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long using namespace std; const ll INF=((ll)1<<63)-1; int T,K; ll m; ll C[106][106]; void chu() { C[0][0]=1; for(int i=1;i<66;++i) C[i][0]=C[i][i]=1; for(int i=1;i<66;++i) for(int j=1;j<i;++j) C[i][j]=C[i-1][j]+C[i-1][j-1]; } ll ji(ll x) { ll ans=0; int cc=0; for(int i=63;i>=0;--i) if( x&((ll)1<<i) ) { //printf("i=%d\n",i); ++cc; if(K-cc>=0) ans+=C[i][K-cc]; } return ans; } ll erl(ll l,ll r) { ll ans=INF,mid; ll temp; while(l<=r) { mid=(l+r)>>1; temp=ji(mid); if(temp==m&&ans>mid&&mid) ans=mid; if(l>=r) break; if(temp>=m) r=mid-1; else l=mid+1; } return ans; } ll err(ll l,ll r) { ll ans=1,mid; ll temp; while(l<=r) { mid=(l+r)>>1; //printf("l=%lld r=%lld mid=%lld\n",l,r,mid); temp=ji(mid); //printf("temp=%lld\n",temp); if(temp==m&&ans<mid) ans=mid; if(l>=r) break; if(temp<=m) l=mid+1; else r=mid-1; } return ans; } int main(){ //freopen("number10.in","r",stdin); //freopen("in.in","r",stdin); //freopen("out.out","w",stdout); chu(); scanf("%d",&T); ll l0,r0; while(T--) { scanf("%lld%d",&m,&K); if(K==0) { printf("0 1\n"); continue; } if(K==1) { printf("-1\n"); continue; } if(K==64) { printf("1 %lld\n",INF); continue; } //K=5; //printf("adsd=%lld\n",ji(97)); l0=erl(0,INF); r0=err(0,INF); printf("%lld %lld\n",l0,r0); } // cout<<(((ll)1<<63)-1); }
以上是关于10.2 上午 考试的主要内容,如果未能解决你的问题,请参考以下文章