- A Araleii & Bill的冠名权争夺战之登顶校赛
————————————————————————————————————————————
我们这样考虑
对于一个说对的概率是1/m ,那么n个人的期望就是n/m
然而这个期望其实就是
E=n/m=∑i=1n(pi×i)(p_i为i个人答对的概率)
pn最大值显然是 n/m=pn×n
所以最后答案就是1/m
这个我当时并不知道这个公式,只是觉得如果我们都能看到对方的帽子的话我只要安排m种颜色的帽子,每个帽子1-m,m+1-m+m…..到n即可。最后得出结论 1/m
B 神奇的身高
————————————————————————————————————————————
队友过得,后期我自己补的他们过的部分题
对于一个序列我们将其变成升序序列,可以直接 a[i]-i 然后求LIS. 但是这样的结果可能是负数或者0的,
然而其实很简单 对于每个a[i]-i 如果小于0 那就一定要变化,所以就对剩下的序列求LIS就可以了,求得的结果就是不用修改的,那么修改的就是n减去
附本题代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N = 100000+7;
const int INF = 2000000007;
int b[N],cnt,n;
int main(){
while(~scanf("%d",&n)){
int mx=0,x;cnt=0;
for(int i=0;i<=n;i++) b[i]=INF;
for(int i=1,id;i<=n;i++){
scanf("%d",&x);x-=i;
if(x<0) continue;
id = upper_bound(b+1,b+1+n,x)-b;
b[id]=x;
mx=mx>id?mx:id;
}
printf("%d\n",n-mx);
}
return 0;
}
——————————————————————————————————————————
C Attack on Titan
队友过得,自己不会- -
————————————————————————————————————————————
D 超级线段树
队友过的,我无耻的把代码和思路复制过来了
————————————————————————————————————————————
这个题简直666 啊
本质就是一个区间覆盖问题,
但是直接区间覆盖会TLE ,然后就一直想怎么做到O(n),,,最后GG了
其实我们可以逆序覆盖,然后每次更新的时候lazy_tag如果有,那就不给它更新了,算是上一个大剪枝了.
附本题代码
————————————————————————————————————————————
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N = 1e6+7;
inline int read(){
int x=0,f=1;char ch = getchar();
while('0'> ch||ch> '9') {if(ch=='-')f=-1;ch=getchar();}
while('0'<=ch&&ch<='9') {x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
int lazy[N<<2];
inline void build(int rt,int l,int r){
lazy[rt]=0;
if(l==r)return;
int m = r+l >> 1;
build(rt<<1 ,l ,m);
build(rt<<1|1,m+1,r);
}
inline void pushdown(int &rt){
if(lazy[rt]){
if(!lazy[rt<<1]) lazy[rt<<1] =lazy[rt];
if(!lazy[rt<<1|1])lazy[rt<<1|1]=lazy[rt];
}
}
inline void update(int rt,int l,int r,int &L,int &R,int &val){
if(lazy[rt]) return ;
if(L<=l&&r<=R){
lazy[rt]=val;
return;
}
pushdown(rt);
int m = r+l >> 1;
if(L<=m) update(rt<<1 ,l ,m,L,R,val);
if(R> m) update(rt<<1|1,m+1,r,L,R,val);
}
inline void visit(int rt,int l,int r){
if(l==r){printf("%d\n",lazy[rt]);return;}
pushdown(rt);
int m = r+l >> 1;
visit(rt<<1 ,l ,m);
visit(rt<<1|1,m+1,r);
}
int l[N],r[N],p[N];
int main(){
int _=read(),n,m;
while(_--){
n=read(),m=read();
build(1,1,n);
for(int i=1;i<=m;i++) l[i]=read(),r[i]=read(),p[i]=read();
for(int i=m;i;i--) update(1,1,n,l[i],r[i],p[i]);
visit(1,1,n);
}
return 0;
}
E rating计算
————————————————————————————————————————————
签到水题,不解释
F 进化之地(Evoland)
————————————————————————————————————————————
当时队友A的,我后期补的
bfs + 细节,注意很多地方,还有就是加一维表示当前地图是几维地图,之后细节判断即可。
#include <bits/stdc++.h>
#define maxs 202020
#define mme(i,j) memset(i,j,sizeof(i))
using namespace std;
int way[5]= {1,0,-1,0};
int wax[5]= {0,1,0,-1};
char maps[102][102];
int n,m,sx,sy;
int ans;
bool vis[102][102][5];
struct node
{
int x,y;
int step;
int state;
} now,nex;
void bfs(int x,int y)// 2-3D
{
mme(vis,0);
now.x=x;
now.y=y;
now.state=2;
now.step=0;
vis[now.x][now.y][now.state]=1;
queue<node>q;
q.push(now);
node tp;
while(!q.empty())
{
now=q.front();
q.pop();
if(maps[now.x][now.y]=='1')
{
printf("%d\n",now.step);
return;
}
for(int i=0; i<4; i++)
{
nex.x=now.x+wax[i];
nex.y=now.y+way[i];
nex.step=now.step+1;
if(nex.x>0&&nex.x<=n&&nex.y>0&&nex.y<=m)
{
if(maps[nex.x][nex.y]=='.'||maps[nex.x][nex.y]=='0'||maps[nex.x][nex.y]=='1')
{
nex.state=now.state;
if(vis[nex.x][nex.y][nex.state]==0)
{
vis[nex.x][nex.y][nex.state]=1;
q.push(nex);
}
}
if(maps[nex.x][nex.y]=='#')continue;
if(maps[nex.x][nex.y]=='@')
{
nex.state=now.state;
if(vis[nex.x][nex.y][nex.state]==0)
{
vis[nex.x][nex.y][nex.state]=1;
q.push(nex);
}
nex.state=5-now.state;
if(vis[nex.x][nex.y][nex.state]==0)
{
vis[nex.x][nex.y][nex.state]=1;
q.push(nex);
}
}
if(maps[nex.x][nex.y] == '2') {
if(now.state==2) {
nex.state=now.state;
if(vis[ nex.x ][ nex.y ][ nex.state ] == 0) {
vis[ nex.x ][ nex.y ][ nex.state ] = 1;
q.push( nex );
}
}
else
continue;
}
if(maps[nex.x][nex.y]=='3'){
if(now.state==3){
nex.state=now.state;
if(vis[nex.x][nex.y][nex.state]==0){
vis[nex.x][nex.y][nex.state]=1;
q.push(nex);
}
}
else
continue;
}
}
}
}
printf("-1\n");
return;
}
void Solve()
{
ans=-1;
sx=sy=-1;
scanf("%d %d",&n,&m);
for(int i=1; i<=n; i++)scanf("%s",maps[i]+1);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
if(maps[i][j]=='0')
{
sx=i;
sy=j;
break;
}
}
if(sx!=-1)
break;
}
if(sx==-1)
{
puts("-1");
return;
}
bfs(sx,sy);
return;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
Solve();
}
return 0;
}
————————————————————————————————————————————
G 贪心
————————————————————————————————————————————
没什么说的直接二分答案就好了
赛后补的题
————————————————————————————————————————————
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long int
struct node
{
ll x,y,ss;
}a[150000];
ll n,m;
ll cmp(node a,node b)
{
return a.ss<b.ss;
}
int Slove(ll mid)
{
ll sum=0;
for(ll j=1;j<=n;j++)a[j].ss=mid*a[j].y+a[j].x;
sort(a+1,a+1+n,cmp);
for(ll j=1;j<=mid;j++)
{
sum+=a[j].ss;
}
if(sum<=m)return 1;
else return 0;
}
int main()
{
while(~scanf("%lld%lld",&n,&m))
{
ll output=0;
for(ll i=1;i<=n;i++)scanf("%lld",&a[i].x);
for(ll i=1;i<=n;i++)scanf("%lld",&a[i].y);
ll l=0;
ll r=n;
while(r-l>=0)
{
ll mid=(l+r)/2;
if(Slove(mid)==1)
{
output=mid;
l=mid+1;
}
else r=mid-1;
}
printf("%lld\n",output);
}
}
————————————————————————————————————————————
H 简单的传球游戏
————————————————————————————————————————————
队友过得
I 打怪兽
————————————————————————————————————————————
K 最长上升子序列(这个未补完)
————————————————
————————————————————————————