1.平面上每次加入直角边平行于坐标轴的等腰直角三角形,每次询问某个点被覆盖了多少次。
大常数算法:O(nlog^2)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=3E5+5; 4 int n,q; 5 inline int read() 6 { 7 char ch=getchar(); 8 while(!isdigit(ch))ch=getchar(); 9 int x=ch-'0'; 10 ch=getchar(); 11 while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} 12 return x; 13 } 14 int G[55]; 15 inline void write(int x) 16 { 17 int g=0; 18 do{G[++g]=x%10;x/=10;}while(x); 19 for(int i=g;i>=1;--i)putchar(G[i]+'0');putchar(' '); 20 } 21 //////////////////////////////////////////////////////////////////////////////////////// splay 22 int t[10000000],fa[10000000],val[10000000],sum[10000000],son[10000000][2],cnt[10000000],TOT; 23 struct Splay 24 { 25 int root; 26 inline void update(int x) 27 { 28 sum[x]=sum[son[x][0]]+sum[son[x][1]]+cnt[x]; 29 } 30 inline void rotate(int x) 31 { 32 int y=fa[x]; 33 int c=son[y][0]==x; 34 fa[x]=fa[y]; 35 son[y][!c]=son[x][c]; 36 if(son[x][c]) 37 fa[son[x][c]]=y; 38 if(son[fa[y]][0]==y) 39 son[fa[y]][0]=x; 40 else 41 son[fa[y]][1]=x; 42 son[x][c]=y; 43 fa[y]=x; 44 update(y); 45 update(x); 46 if(y==root) 47 root=x; 48 } 49 inline void splay(int x) 50 { 51 if(x==root) 52 return; 53 while(true) 54 { 55 int y=fa[x]; 56 if(y==0) 57 break; 58 if(y==root) 59 { 60 rotate(x); 61 break; 62 } 63 if((son[fa[y]][0]==y)==(son[y][0]==x)) 64 rotate(y),rotate(x); 65 else 66 rotate(x),rotate(x); 67 } 68 } 69 inline void insert(int x) 70 { 71 if(root==0) 72 { 73 root=++TOT; 74 sum[root]=cnt[root]=1; 75 val[root]=x; 76 return; 77 } 78 int pos=root; 79 while(true) 80 { 81 ++sum[pos]; 82 if(val[pos]==x) 83 { 84 ++cnt[pos]; 85 break; 86 } 87 if(x<val[pos]) 88 { 89 if(son[pos][0]==0) 90 { 91 son[pos][0]=++TOT; 92 sum[TOT]=cnt[TOT]=1; 93 val[TOT]=x; 94 fa[TOT]=pos; 95 break; 96 } 97 pos=son[pos][0]; 98 } 99 else 100 { 101 if(son[pos][1]==0) 102 { 103 son[pos][1]=++TOT; 104 sum[TOT]=cnt[TOT]=1; 105 val[TOT]=x; 106 fa[TOT]=pos; 107 break; 108 } 109 pos=son[pos][1]; 110 } 111 } 112 // splay(pos); 113 } 114 inline int askSmaller(int x)// how many numbers are <= x 115 { 116 int ans=0; 117 int pos=root; 118 while(pos) 119 { 120 if(x<val[pos]) 121 pos=son[pos][0]; 122 else 123 { 124 ans+=sum[son[pos][0]]+cnt[pos]; 125 pos=son[pos][1]; 126 } 127 } 128 return ans; 129 } 130 inline int askBigger(int x)// how many numbers are >= x 131 { 132 int ans=0; 133 int pos=root; 134 while(pos) 135 { 136 if(x>val[pos]) 137 pos=son[pos][1]; 138 else 139 { 140 ans+=sum[son[pos][1]]+cnt[pos]; 141 pos=son[pos][0]; 142 } 143 } 144 return ans; 145 } 146 void out() 147 { 148 cout<<root<<endl; 149 cout<<"FA :";for(int i=1;i<=TOT;++i)cout<<fa[i]<<" ";cout<<endl; 150 cout<<"SUM :";for(int i=1;i<=TOT;++i)cout<<sum[i]<<" ";cout<<endl; 151 cout<<"VAl :";for(int i=1;i<=TOT;++i)cout<<val[i]<<" ";cout<<endl; 152 cout<<"SON :";for(int i=1;i<=TOT;++i)cout<<son[i][0]<<" ";cout<<endl; 153 cout<<" :";for(int i=1;i<=TOT;++i)cout<<son[i][1]<<" ";cout<<endl; 154 } 155 }; 156 //////////////////////////////////////////////////////////////////////////////////////// 157 struct Segment 158 { 159 Splay T[maxn*4]; 160 inline void add(int L,int R,int l,int r,int x,int num) 161 { 162 if(L<=l&&r<=R) 163 { 164 T[num].insert(x); 165 return; 166 } 167 int mid=(l+r)>>1; 168 if(R<=mid) 169 add(L,R,l,mid,x,num<<1); 170 else if(mid<L) 171 add(L,R,mid+1,r,x,num<<1|1); 172 else 173 add(L,R,l,mid,x,num<<1),add(L,R,mid+1,r,x,num<<1|1); 174 } 175 inline int askSmaller(int l,int r,int pos,int x,int num)// <= 176 { 177 if(l==r) 178 return T[num].askSmaller(x); 179 int mid=(l+r)>>1; 180 if(pos<=mid) 181 return askSmaller(l,mid,pos,x,num<<1)+T[num].askSmaller(x); 182 else 183 return askSmaller(mid+1,r,pos,x,num<<1|1)+T[num].askSmaller(x); 184 } 185 inline int askBigger(int l,int r,int pos,int x,int num)// >= 186 { 187 if(l==r) 188 return T[num].askBigger(x); 189 int mid=(l+r)>>1; 190 if(pos<=mid) 191 return askBigger(l,mid,pos,x,num<<1)+T[num].askBigger(x); 192 else 193 return askBigger(mid+1,r,pos,x,num<<1|1)+T[num].askBigger(x); 194 } 195 }T[8]; 196 int main() 197 { 198 freopen("frontier.in","r",stdin); 199 freopen("frontier.out","w",stdout); 200 ios::sync_with_stdio(false); 201 int useless=read(); 202 n=read(),q=read(); 203 while(q--) 204 { 205 int opt=read(); 206 if(opt==1) 207 { 208 opt=read(); 209 int x=read(),y=read(),z=read(); 210 if(opt==1) 211 { 212 T[0].add(y,y+z,1,n,x+y+z,1); 213 T[1].add(y,y+z,1,n,x-1,1); 214 } 215 else if(opt==2) 216 { 217 T[2].add(y-z,y,1,n,x-(y-z),1); 218 T[1].add(y-z,y,1,n,x-1,1); 219 } 220 else if(opt==3) 221 { 222 T[4].add(y,y+z,1,n,x-(y+z),1); 223 T[5].add(y,y+z,1,n,x+1,1); 224 } 225 else 226 { 227 T[6].add(y-z,y,1,n,x+y-z,1); 228 T[5].add(y-z,y,1,n,x+1,1); 229 } 230 } 231 else 232 { 233 int x=read(),y=read(); 234 int ans1=T[0].askBigger(1,n,y,x+y,1)-T[1].askBigger(1,n,y,x,1); 235 int ans2=T[2].askBigger(1,n,y,x-y,1); 236 int ans3=T[4].askSmaller(1,n,y,x-y,1)-T[5].askSmaller(1,n,y,x,1); 237 int ans4=T[6].askSmaller(1,n,y,x+y,1); 238 write(ans1+ans2+ans3+ans4); 239 } 240 } 241 return 0; 242 }
离线做法:还没写
2.
小L 的治疗总共分为N 个阶段,在第i 个阶段,小L 可以做出如下选择: 1.施放治愈法术,为永恒之树恢复xi + S 点生命力 2.为法杖注入能量,令法术强度S 增加yi 3.吟唱圣歌,召唤zi只木精灵 在每个阶段结束时,每只木精灵会使得法术强度S增加1 请帮助小L 计算在N个阶段结束后,能够为永恒之树恢复的最大生命力。
n <= 80
简单题。n^4
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long int ll; 4 const ll inf=1E15; 5 ll f[85][85][85*85]; 6 ll n,a[85],b[85],c[85]; 7 inline ll max(ll x,ll y) 8 { 9 return x>y?x:y; 10 } 11 inline void U(ll&x,ll y) 12 { 13 x=max(x,y); 14 } 15 inline void solve() 16 { 17 cin>>n; 18 for( 19 int i=1;i<=n;++i) 20 cin>>a[i]>>b[i]>>c[i]; 21 for(int i=0;i<=n;++i) 22 for(int j=0;j<=n;++j) 23 for(int k=0;k<=n*n;++k) 24 f[i][j][k]=-inf; 25 f[n][0][0]=0; 26 f[n][1][0]=a[n]; 27 for(int i=n;i>=2;--i) 28 { 29 for(int j=0;j<=n;++j) 30 { 31 for(int k=0;k<=n*n;++k) 32 { 33 U(f[i-1][j+1][j+k],f[i][j][k]+a[i-1]); 34 U(f[i-1][j][j+k],f[i][j][k]+b[i-1]*j); 35 U(f[i-1][j][j+k],f[i][j][k]+c[i-1]*(j+k)); 36 } 37 } 38 } 39 ll ans=0; 40 for(int i=1;i<=n;++i) 41 for(int j=0;j<=n*n;++j) 42 ans=max(ans,f[1][i][j]); 43 cout<<ans<<endl; 44 } 45 int main() 46 { 47 freopen("fortune.in","r",stdin); 48 freopen("fortune.out","w",stdout); 49 ios::sync_with_stdio(false); 50 int useless,T; 51 cin>>useless>>T; 52 while(T--) 53 solve(); 54 return 0; 55 }
3.
在小L 的努力下,永恒之树已经恢复了生命力。 渐渐恢复元气的X 国将进行一次占卜仪式,在仪式中,小L 将取下一段永恒之树的树枝。这里,我们将一段树枝抽象成 一张N个点,M 条边的无向图,恢复了生命力的永恒之树已经脱离了普通的树的范畴,但仍然具备一些树的特性,譬如每条边 都只在至多一个简单环中出现。 小L 将对取下的树枝使用分解魔法,此后,树枝的每一个节点都会在一个时辰内随机的一个时刻,连同其连出去的边一 起被分解。在被分解的瞬间,每个节点会释放出等同于当时还与其连通的节点数量的能量,将这些能量求和,便得到了X 国的 气运。 现在,小L 想要知道,X 国的气运期望会是多少。 请求出X 国气运的期望对998244353 取模的结果。
即求一个仙人掌随机点分治的期望复杂度。
若仙人掌是一棵树,考虑一对点之间的贡献。即x对y产生贡献,即x在被选中前始终与y联通的概率,为$frac{1}{dist(x,y)}$,dist为两点之间的点的个数。