Beautiful Now
题意:
定义一次合法的交换(i,j)为交换n的第i位与第j位数且不能出现前导0(i和j可以相同),问n经过k次交换后的最小值和最大值分别是多少。
分析:
贪心是原罪啊,后来写了个bfs过了,注意下剪枝就好了。对于求最大值,如果arr【i】< arr【j】且arr【j】为n的第i+1位到末尾上的最大值,才进行交换;如果已经达到所能循环的最大值直接跳出循环。对于求最小值也是同理,不过对于前导0的情况特判掉就好了。比赛代码写的臭长臭长的,就不贴了。
Everything Has Changed
题意:
给出一个圆盘,给出n个小圆的圆心和半径,每次从圆盘中切去小圆(大圆小圆不一定有交集),保证小圆没有交集且没有一个小圆包含整个圆,问最后圆盘的周长是多少?
分析:
余弦定理求出角度,然后算出弧长就好了。
代码:
#include <map> #include <queue> #include <math.h> #include <string> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; #define ll long long #define ui unsigned int #define ull unsigned long long #define cls(x) memset(x,0,sizeof(x)) #define clslow(x) memset(x,-1,sizeof(x)) const int maxn=1e5+100; const double PI=acos(-1.0); int n,R,x,y,r,T; double normal(double x) { return min(max(-1.0,x),1.0); } double getangle(int a,int b,int c) { double cosa=(a+b-c)*1.0/(2*sqrt(a)*sqrt(b)); return acos(normal(cosa)); } int main() { // freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { scanf("%d%d",&n,&R); double p=2.0*PI*R; for(int i=1;i<=n;i++){ scanf("%d%d%d",&x,&y,&r); //外切和外离 if(x*x+y*y>=(R+r)*(R+r)) continue; //包含 if(x*x+y*y<(R-r)*(R-r)) continue; //内切 if(x*x+y*y==(R-r)*(R-r)){ p+=2*PI*r; continue; } //相交 double arc1=2.0*getangle(R*R,x*x+y*y,r*r)*R; double arc2=2.0*getangle(r*r,x*x+y*y,R*R)*r; p-=arc1;p+=arc2; } printf("%lf ",p); } return 0; }
Glad You Came
题意:
给出m次操作,每次操作包含3个数l,r,v,对于a数组如果a【l】……a【r】存在有值小于v,则把该值更新为v,求(1*a【1】)^(2*a【2】)……^(n*a【n】)的值。
分析:
暴力更新肯定是不行的,考虑使用线段树或者st表来维护区间的最小值,如果某段区间的最小值小于v,则更新区间。
代码:
线段树
#include <map> #include <queue> #include <math.h> #include <string> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; #define ll long long #define ui unsigned int #define ull unsigned long long #define cls(x) memset(x,0,sizeof(x)) #define clslow(x) memset(x,-1,sizeof(x)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn=1e5+100; const int maxm=5e6+100; ll ans; int n,m,T; ui x,y,z; ui f[maxm*3]; ll minval[maxn<<2]; ui getf(ui& x,ui& y,ui& z) { x^=(x<<11); x^=(x>>4); x^=(x<<5); x^=(x>>14); ui w=x^(y^z); x=y; y=z; z=w; return z; } void PushUp(int rt) { minval[rt]=min(minval[rt<<1],minval[rt<<1|1]); } void PushDown(int rt) { if(minval[rt]){ minval[rt<<1]=max(minval[rt],minval[rt<<1]); minval[rt<<1|1]=max(minval[rt],minval[rt<<1|1]); minval[rt]=0; } } void build(int l,int r,int rt) { if(l==r){ minval[rt]=0; return; } int m=(l+r)>>1; build(lson); build(rson); PushUp(rt); } void update(int L,int R,int val,int l,int r,int rt) { if(minval[rt]>=val) return; if(L<=l&&r<=R){ minval[rt]=val; return; } PushDown(rt); int m=(l+r)>>1; if(L<=m) update(L,R,val,lson); if(R>m) update(L,R,val,rson); PushUp(rt); } void query(int l,int r,int rt) { if(l==r){ ans=ans^((ll)l*minval[rt]); return; } PushDown(rt); int m=(l+r)>>1; query(lson); query(rson); } void debug(int l,int r,int rt) { if(l==r){ cout<<l<<" "<<minval[rt]<<endl; return; } PushDown(rt); int m=(l+r)>>1; debug(lson); debug(rson); } int main() { // freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { scanf("%d %d %u %u %u",&n,&m,&x,&y,&z); for(int i=1;i<=m*3;i++){ f[i]=getf(x,y,z); } build(1,n,1); for(int i=1;i<=m;i++){ int l,r,v; l=min(f[3*i-2]%n+1,f[3*i-1]%n+1); r=max(f[3*i-2]%n+1,f[3*i-1]%n+1); v=f[3*i]%(1<<30); update(l,r,v,1,n,1); } ans=0; // debug(1,n,1); query(1,n,1); printf("%lld ",ans); } return 0; }
ST表
#include <map> #include <queue> #include <math.h> #include <string> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; #define ll long long #define ui unsigned int #define ull unsigned long long #define cls(x) memset(x,0,sizeof(x)) #define clslow(x) memset(x,-1,sizeof(x)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn=1e5+100; const int maxm=5e6+100; ll ans; int n,m,T; ui x,y,z; ui f[maxm*3]; int lg2[maxn]; ui getf(ui& x,ui& y,ui& z) { x^=(x<<11); x^=(x>>4); x^=(x<<5); x^=(x>>14); ui w=x^(y^z); x=y; y=z; z=w; return z; } void getlg2() { lg2[1]=0; for(int i=2;i<maxn;i++){ lg2[i]=lg2[i/2]+1; } } struct ST { int d[maxn][20]; void init(int n) { int len=lg2[n]; for(int i=0;i<=len;i++){ for(int j=1;j<=n;j++){ d[j][i]=0; } } } void update(int l,int r,int val) { int len=lg2[r-l+1]; d[l][len]=max(val,d[l][len]); d[r-(1<<len)+1][len]=max(val,d[r-(1<<len)+1][len]); } ll query(int l,int r) { int len=lg2[r-l+1]; for(int i=len;i>=1;i--){ for(int j=l;j<=r;j++){ if(j+(1<<i)-1>r) break; d[j][i-1]=max(d[j][i],d[j][i-1]); d[j+(1<<(i-1))][i-1]=max(d[j][i],d[j+(1<<(i-1))][i-1]); } } ll res=0; for(int i=l;i<=r;i++){ res=res^((ll)d[i][0]*i); } return res; } }; ST st; int main() { // freopen("in.txt","r",stdin); getlg2(); scanf("%d",&T); while(T--) { scanf("%d %d %u %u %u",&n,&m,&x,&y,&z); for(int i=1;i<=m*3;i++){ f[i]=getf(x,y,z); } st.init(n); for(int i=1;i<=m;i++){ int l,r,v; l=min(f[3*i-2]%n+1,f[3*i-1]%n+1); r=max(f[3*i-2]%n+1,f[3*i-1]%n+1); v=f[3*i]%(1<<30); st.update(l,r,v); } printf("%lld ",st.query(1,n)); } return 0; }