11.2 模拟赛
菜的很的我又被踩了 耻辱#6
T1 meet
题目大意:
数轴上两个点x y 可以左移 右移1单位 或坐标*2 求最少步数
思路:
sb题 bfs就完事了
(我更sb 开始想错了以为有负数开小了空间)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #define inf 2139062143 11 #define ll long long 12 #define MAXN 300100 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 //yyc score=0 22 int n,k,q[MAXN<<3],l,r,vis[(MAXN<<1)+100]; 23 int main() 24 { 25 freopen("meet.in","r",stdin); 26 freopen("meet.out","w",stdout); 27 n=read(),k=read();q[l=r=1]=n,vis[n]=1;int x; 28 if(n>=k) return printf("%d\n",n-k)&0; 29 while(l<=r) 30 { 31 x=q[l++]; 32 if(x==k) break; 33 if(!vis[x+1]) vis[x+1]=vis[x]+1,q[++r]=x+1; 34 if(!vis[x-1]&&x-1>=0) vis[x-1]=vis[x]+1,q[++r]=x-1; 35 if(!vis[x*2]&&x*2<=4*k) vis[x*2]=vis[x]+1,q[++r]=x<<1; 36 } 37 printf("%d\n",vis[k]-1); 38 }
T2 sum
题目大意:
求一个数列的K阶前缀和数组
思路:
推一下式子发现是组合数
(然而我过于sb 没考虑n>k的情况)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #define inf 2139062143 11 #define ll long long 12 #define MAXN 5100 13 #define MOD 1000000007 14 using namespace std; 15 inline int read() 16 { 17 int x=0,f=1;char ch=getchar(); 18 while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();} 19 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 20 return x*f; 21 } 22 //yyc score=0 23 ll n,k,a[MAXN],x[MAXN],ans[MAXN]; 24 ll q_pow(ll bas,ll t) 25 { 26 ll res=1; 27 for(;t;t>>=1,(bas*=bas)%=MOD) 28 if(t&1) (res*=bas)%=MOD; 29 return res; 30 } 31 ll C(ll n,ll m) 32 { 33 if(n<m) return 0LL; 34 ll a=1LL,b=1LL; 35 while(m) (a*=n)%=MOD,(b*=m)%=MOD,n--,m--; 36 return a*q_pow(b,MOD-2)%MOD; 37 } 38 int main() 39 { 40 freopen("sum.in","r",stdin); 41 freopen("sum.out","w",stdout); 42 n=read(),k=read()-1; 43 for(int i=1;i<=n;i++) a[i]=read(); 44 for(int i=x[0]=1;i<=n;i++) x[i]=C(k+i,i); 45 for(int i=1;i<=n;i++) 46 for(int t=0;t<i;t++) (ans[i]+=a[i-t]*x[t])%=MOD; 47 for(int i=1;i<=n;i++) printf("%lld ",ans[i]); 48 }
T3 xiaoqiao
题目大意:
极坐标(已被均分)染色
求被染过至少k次的面积
思路:
一看到题就快乐主席树结果不但写挂了还算错了空间会MLE
(非常不优秀的主席树代码得了95)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #define inf 2139062143 11 #define ll long long 12 #define MAXN 200100 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 //yyc score=0 22 int tot,n,m,lmt,rt[MAXN]; 23 ll ans; 24 struct opt{int l,r,val;}q[MAXN]; 25 struct node{int ls,rs,val;}tr[MAXN<<6]; 26 bool cmp(const opt &a,const opt &b) {return a.val<b.val;} 27 void mdf(int &k,int kk,int l,int r,int a,int b) 28 { 29 if(!k) k=++tot,tr[k]=tr[kk]; 30 if(l==a&&r==b) {tr[k].val++;return ;} 31 int mid=l+r>>1; 32 if(b<=mid) {tr[k].ls=0;mdf(tr[k].ls,tr[kk].ls,l,mid,a,b);} 33 else if(a>mid) {tr[k].rs=0;mdf(tr[k].rs,tr[kk].rs,mid+1,r,a,b);} 34 else {tr[k].ls=tr[k].rs=0;mdf(tr[k].ls,tr[kk].ls,l,mid,a,mid);mdf(tr[k].rs,tr[kk].rs,mid+1,r,mid+1,b);} 35 } 36 int v; 37 inline void queryv(int k,int l,int r,int x) 38 { 39 register int mid; 40 while(l!=r) 41 { 42 v+=tr[k].val,mid=l+r>>1; 43 if(x<=mid) r=mid,k=tr[k].ls;else l=mid+1,k=tr[k].rs; 44 } 45 v+=tr[k].val; 46 } 47 int main() 48 { 49 freopen("xiaoqiao.in","r",stdin); 50 freopen("xiaoqiao.out","w",stdout); 51 m=read(),n=read(),lmt=read();register int a,b,c; 52 for(register int i=1;i<=m;++i) 53 { 54 c=read(),a=read(),b=read(); 55 if(a==n) a=-n;if(b==-n) b=n; 56 if(a<b) q[++tot].val=c,q[tot].l=a+n+1,q[tot].r=b+n; 57 else if(a+b==0) q[++tot].val=c,q[tot].l=1,q[tot].r=n; 58 else 59 { 60 q[++tot].val=c,q[tot].l=a+n+1,q[tot].r=n<<1; 61 q[++tot].val=c,q[tot].l=1,q[tot].r=b+n; 62 } 63 } 64 m=tot,n<<=1,tot=0;register int l,r,mid,res,Goal; 65 sort(q+1,q+m+1,cmp); 66 for(register int i=1;i<=m;++i) 67 { 68 //cout<<q[i].l<<" "<<q[i].r<<" "<<q[i].val<<endl; 69 mdf(rt[i],rt[i-1],1,n,q[i].l,q[i].r); 70 } 71 for(register int i=1;i<=n;++i) 72 { 73 l=1,r=m,res=v=0;queryv(rt[m],1,n,i); 74 if(v<lmt) continue;Goal=v-lmt+1; 75 while(l<=r) 76 { 77 mid=l+r>>1,v=0;queryv(rt[mid],1,n,i); 78 if(v>=Goal) r=mid-1,res=mid; 79 else l=mid+1; 80 } 81 ans+=(ll)q[res].val*q[res].val; 82 //cout<<i<<" "<<res<<" "<<q[res].val<<endl; 83 } 84 printf("%lld\n",ans); 85 }
正解应该是差分+扫描线
或使用平衡树/权值线段树 维护单点+ - 以及第k大 ($log$
(放上石神优秀的树状数组 $log^2$)
1 #include<algorithm> 2 #include<cmath> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<ctime> 7 #include<iomanip> 8 #include<iostream> 9 #include<map> 10 #include<stack> 11 #include<queue> 12 #include<vector> 13 #define rep(i,x,y) for(int i=(x);i<=(y);++i) 14 #define dwn(i,x,y) for(int i=(x);i>=(y);--i) 15 #define LL long long 16 #define maxn 200010 17 using namespace std; 18 int read() 19 { 20 int x=0,f=1;char ch=getchar(); 21 while(!isdigit(ch)&&ch!='-')ch=getchar(); 22 if(ch=='-')ch=getchar(),f=-1; 23 while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); 24 return x*f; 25 } 26 void write(LL x) 27 { 28 if(x==0){putchar('0'),putchar('\n');return;} 29 if(x<0)putchar('-'),x=-x; 30 int f=0;char ch[20]; 31 while(x)ch[++f]=x%10+'0',x/=10; 32 while(f)putchar(ch[f--]); 33 putchar('\n'); 34 return; 35 } 36 int n,m,k,qr,qs,qt,tr[maxn]; 37 int tpr; 38 LL ans; 39 int lt(int x){return x&(-x);} 40 void add(int x,int k){for(;x<=tpr;x+=lt(x))tr[x]+=k;return;} 41 int ask(int x){int k=0;for(;x;x-=lt(x))k+=tr[x];return k;} 42 vector<int>ad[maxn],de[maxn]; 43 int gx(int x){return m-x;} 44 int nxt(int x){if(x>(m<<1))return x-(m<<1);if(x<1)return (m<<1)-x;return x;} 45 int main() 46 { 47 freopen("xiaoqiao.in","r",stdin); 48 freopen("xiaoqiao.out","w",stdout); 49 n=read(),m=read(),k=read(); 50 rep(i,1,n) 51 { 52 qr=read(),qs=read(),qt=read(); 53 qs=gx(qs),qt=gx(qt),qt=nxt(qt+1),qs=nxt(qs),swap(qs,qt); 54 if(qs<=qt) 55 { 56 ad[qs].push_back(qr),de[qt+1].push_back(qr); 57 } 58 else 59 { 60 ad[1].push_back(qr),de[qt+1].push_back(qr); 61 ad[qs].push_back(qr),de[m*2+1].push_back(qr); 62 } 63 tpr=max(tpr,qr); 64 }tpr++;int li=m*2; 65 rep(i,1,li) 66 { 67 int lim=ad[i].size()-1; 68 rep(j,0,lim)add(1,1),add(ad[i][j]+1,-1); 69 lim=de[i].size()-1; 70 rep(j,0,lim)add(1,-1),add(de[i][j]+1,1); 71 int L=1,R=tpr,maxl=0; 72 while(L<=R) 73 { 74 int mid=(L+R>>1); 75 int tmp=ask(mid); 76 if(tmp>=k)maxl=max(maxl,mid),L=mid+1; 77 else R=mid-1; 78 } 79 ans+=(LL)maxl*(LL)maxl; 80 } 81 write(ans); 82 return 0; 83 } 84 /* 85 4 8 2 86 3 -8 8 87 3 -7 3 88 3 -5 5 89 3 7 6 90 */