2026寒假牛客 2.13

赛时ac:7

赛后ac:8

A:

注意到w是整数,每次的修改值也是整数,这样我们就可以把每一次修改离散出来,具体的,假设我们一单位长度一单位长度的修改,对于每一个尺子来说,该次修改的贡献值是可以计算的,我们用优先队列维护这个贡献,每次取最大即可

code:

#include<bits/stdc++.h>

#define int long long

#define inf 0x3f3f3f3f3f3f3f

#define GG ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

#define cnot cout<<"NO"<<"\n"

#define cyes cout<<"YES"<<"\n"

#define cans cout<<ans<<"\n"

#define pb push_back

#define x0 first

#define y0 second

#define lc p<<1

#define rc p<<1|1

#define mem(a,b) memset(a,b,sizeof(a))

#define sp(x) fixed<<setprecision(x)

#define all(v) v.begin(),v.end()

#define fr(i,st,ed) for(int i=st;i<=ed;i++)

#define ffr(i,st,ed,dt) for(int i=st;i<=ed;i+=dt)

using namespace std;

typedef pair<int,string>Pis;

typedef pair<int,int>Pii;

const int N=2e4+10,mod=998244353,M=1e6+10;

int lowbit(int x){

return x&(-x);}

struct Node{

double val;

int id;

int cnt;

bool operator<(const Node&other)const{

return val<other.val;

}

};

double V(Pii a,int t){

double x1=1.0*a.x0;

double x2=1.0*a.x0;

double y1=1.0*a.y0-1.0*t+1.0;

double y2=1.0*a.y0-1.0*t;

double v=sqrt(x1*x1+y1*y1)-sqrt(x1*x1+y2*y2);

return v;

}

void solve(){

int n,w;

cin>>n>>w;

vector<Pii>vec(n);

double tot=0;

priority_queue<Node>q;

fr(i,0,n-1){

cin>>vec[i].x0>>vec[i].y0;

tot+=sqrt((double)vec[i].x0*(double)vec[i].x0+(double)vec[i].y0*(double)vec[i].y0);

if(vec[i].y0>0){

q.push({V(vec[i],1),i,1});

}

}

while(w>0&&!q.empty()){

Node t=q.top();

q.pop();

tot-=t.val;

w--;

if(t.cnt<vec[t.id].y0){

int cc=t.cnt+1;

q.push({V(vec[t.id],cc),t.id,cc});

}

}

cout<<sp(10)<<tot<<"\n";

}

signed main(){

GG;

int _t=1;

//cin>>_t;

while(_t--){

solve();

}

}

B

高中数学题,问题的本质是把连续的数字分成k段有几种分法,答案很显然是C(n-1,k-1),令最终要分t段,t&1时,很显然左右各有(t+1)/2段,等价于把左右的数分这么多段的方法数相乘再*2(左前/右前),tmod2=0,分别有t/2,t/2+1段,分别考虑左前/右前,可能数相乘即可

code:

#include<bits/stdc++.h>

#define int long long

#define inf 0x3f3f3f3f3f3f3f

#define GG ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

#define cnot cout<<"NO"<<"\n"

#define cyes cout<<"YES"<<"\n"

#define cans cout<<ans<<"\n"

#define pb push_back

#define x0 first

#define y0 second

#define lc p<<1

#define rc p<<1|1

#define mem(a,b) memset(a,b,sizeof(a))

#define sp(x) fixed<<setprecision(x)

#define all(v) v.begin(),v.end()

#define fr(i,st,ed) for(int i=st;i<=ed;i++)

#define ffr(i,st,ed,dt) for(int i=st;i<=ed;i+=dt)

using namespace std;

typedef pair<int,string>Pis;

typedef pair<int,int>Pii;

const int N=2e4+10,mod=998244353,M=1e6+10;

int lowbit(int x){

return x&(-x);}

vector<int>f(M),inv(M);

int qmi(int a,int b,int p)

{

int res=1;

while (b){

if (b&1)res=res*a%p;

a=a*(int)a%p;

b>>=1;

}

return res;

}

int inp(int x){

return qmi(x,mod-2,mod);

}

void P(){

f[0]=1;

inv[0]=1;

fr(i,1,M-1){

f[i]=(f[i-1]*i)%mod;

}

inv[M-1]=inp(f[M-1]);

for(int i=M-2;i>=1;i--){

inv[i]=(inv[i+1]*(i+1))%mod;

}

}

int C(int n,int k){

if(k<0||k>n)return 0;

return f[n]*inv[k]%mod*inv[n-k]%mod;

}

int SC(int n,int k){

return C(n-1,k-1);

}

void solve(){

int n,x,t;

cin>>n>>x>>t;

if(x==n){

if(t==0){

cout<<1<<"\n";

return;

}

else{

cout<<0<<"\n";

return;

}

}

if(t==0&&x!=n){

cout<<0<<"\n";

return;

}

int ans=0;

if(t&1){

int z=(t+1)/2;

ans=2*SC(x,z)*SC(n-x,z)%mod;

}

else{

int z1=t/2;

int z2=t/2+1;

ans=SC(x,z1)*SC(n-x,z2)%mod+SC(x,z2)*SC(n-x,z1)%mod;

}

ans=ans%mod;

cans;

}

signed main(){

GG;

int _t=1;

cin>>_t;

P();

while(_t--){

solve();

}

}

C线段树模板题,很显然线段树需要维护的信息为是否被破坏,查询存在一个优化是维护一个int val表示查询该区间需要的代价,初始所有val =1,如果存在该节点被破坏,val[p]=val[p<<1]+val[p<<1|1](需要从下面的节点获取信息),注意向上维护即可

code:

#include<bits/stdc++.h>

#define int long long

#define inf 0x3f3f3f3f3f3f3f

#define GG ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

#define cnot cout<<"NO"<<"\n"

#define cyes cout<<"YES"<<"\n"

#define cans cout<<ans<<"\n"

#define pb push_back

#define x0 first

#define y0 second

#define lc p<<1

#define rc p<<1|1

#define mem(a,b) memset(a,b,sizeof(a))

#define sp(x) fixed<<setprecision(x)

#define all(v) v.begin(),v.end()

#define fr(i,st,ed) for(int i=st;i<=ed;i++)

#define ffr(i,st,ed,dt) for(int i=st;i<=ed;i+=dt)

using namespace std;

typedef pair<int,string>Pis;

typedef pair<int,int>Pii;

const int N=1e6+10,mod=998244353,M=1e6+10;

int lowbit(int x){

return x&(-x);}

struct Node{

bool flag;

int val;

};

vector<Node>tree;

void up(int p){

tree[p].val=tree[lc].val+tree[rc].val;

}

void build(int p,int l,int r){

tree[p].flag=0;

tree[p].val=1;

if(l==r){

return;

}

int mid=(l+r)>>1;

build(lc,l,mid);

build(rc,mid+1,r);

//return;

}

void upd(int p,int l,int r,int nl,int nr){

if(l>=nl&&r<=nr){

if(!tree[p].flag){

tree[p].flag=1;

up(p);

}

return;

}

int mid=(l+r)>>1;

if(nl<=mid)upd(lc,l,mid,nl,nr);

if(nr>mid)upd(rc,mid+1,r,nl,nr);

if(tree[p].flag)up(p);

return;

}

int que(int p,int l,int r,int nl,int nr){

if(l>=nl&&r<=nr){

return tree[p].val;

}

int res=(tree[p].flag?0:1);

int mid=(l+r)>>1;

if(nl<=mid)res+=que(lc,l,mid,nl,nr);

if(nr>mid)res+=que(rc,mid+1,r,nl,nr);

return res;

}

void solve(){

int n;

cin>>n;

tree.resize((n<<2)+100);

int m=n;

build(1,1,n);

while(m--){

int op,l,r;

cin>>op>>l>>r;

if(op==1)upd(1,1,n,l,r);

else cout<<que(1,1,n,l,r)<<"\n";

}

}

signed main(){

GG;

int _t=1;

//cin>>_t;

while(_t--){

solve();

}

}

Ddij模板题,往下一格的代价是当前格时间加1和便白时间取max

#include<bits/stdc++.h>

#define int long long

#define inf 0x3f3f3f3f3f3f3f

#define GG ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

#define cnot cout<<"NO"<<"\n"

#define cyes cout<<"YES"<<"\n"

#define cans cout<<ans<<"\n"

#define pb push_back

#define x0 first

#define y0 second

#define lc p<<1

#define rc p<<1|1

#define mem(a,b) memset(a,b,sizeof(a))

#define sp(x) fixed<<setprecision(x)

#define all(v) v.begin(),v.end()

#define fr(i,st,ed) for(int i=st;i<=ed;i++)

#define ffr(i,st,ed,dt) for(int i=st;i<=ed;i+=dt)

using namespace std;

typedef pair<int,string>Pis;

typedef pair<int,int>Pii;

const int N=2e4+10,mod=998244353,M=1e6+10;

int lowbit(int x){

return x&(-x);}

struct Node{

int x,y,t;

bool operator>(const Node&other)const{

return t>other.t;

}

};

int dx[]={0,0,-1,1};

int dy[]={-1,1,0,0};

void solve(){

int n,m,a,b;

cin>>n>>m>>a>>b;

map<Pii,int>mp;

vector<vector<int>>g(n+1,vector<int>(m+1));//0 white 1black 2blue

vector<vector<int>>dist(n+1,vector<int>(m+1,inf));

vector<vector<int>>bt(n+1,vector<int>(m+1));

//queue<Node>q;

priority_queue<Node,vector<Node>,greater<Node>>q;

fr(i,1,a){

int x,y;

cin>>x>>y;

g[x][y]=1;

dist[x][y]=0;

q.push({x,y,0});

}

fr(i,1,b){

int x,y,t;

cin>>x>>y>>t;

g[x][y]=2;

//mp[{x,y}]=t;

bt[x][y]=t;

}

int ans=0;

while(!q.empty()){

Node tot=q.top();

q.pop();

int tx=tot.x;

int ty=tot.y;

int tm=tot.t;

if(tm>dist[tx][ty])continue;

ans=max(ans,tm);

fr(i,0,3){

int nx=tx+dx[i];

int ny=ty+dy[i];

if(nx>=1&&nx<=n&&ny>=1&&ny<=m){

int nt=max(tm+1,bt[nx][ny]);

if(nt<dist[nx][ny]){

dist[nx][ny]=nt;

q.push({nx,ny,nt});

}

}

}

}

cans;

}

signed main(){

GG;

int _t=1;

//cin>>_t;

while(_t--){

solve();

}

}

E正难则反,考虑反着来,逐步把城市加入进去,并查集维护连通块大小即可

code:

#include<bits/stdc++.h>

#define int long long

#define inf 0x3f3f3f3f3f3f3f

#define GG ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

#define cnot cout<<"NO"<<"\n"

#define cyes cout<<"YES"<<"\n"

#define cans cout<<ans<<"\n"

#define pb push_back

#define x0 first

#define y0 second

#define lc p<<1

#define rc p<<1|1

#define mem(a,b) memset(a,b,sizeof(a))

#define sp(x) fixed<<setprecision(x)

#define all(v) v.begin(),v.end()

#define fr(i,st,ed) for(int i=st;i<=ed;i++)

#define ffr(i,st,ed,dt) for(int i=st;i<=ed;i+=dt)

using namespace std;

typedef pair<int,string>Pis;

typedef pair<int,int>Pii;

const int N=2e4+10,mod=998244353,M=1e6+10;

int lowbit(int x){

return x&(-x);}

int n,m,x;

vector<int>f,sz,as,h;

vector<bool>st;

vector<Pii>a;

vector<vector<int>>g;

int cnt=0;

int minx;

int find(int x){

return x==f[x]?x:f[x]=find(f[x]);

}

void upd(int x,int y){

int X=find(x);

int Y=find(y);

if(X!=Y){

if(sz[X]>=minx)cnt--;

if(sz[Y]>=minx)cnt--;

f[Y]=X;

sz[X]+=sz[Y];

if(sz[X]>=minx)cnt++;

}

}

bool cmp(Pii a,Pii b){

return a.x0>b.x0;

}

void solve(){

cin>>n>>m>>x>>minx;

f.resize(n+1);

sz.resize(n+1);

st.resize(n+1);

as.resize(x+1);

h.resize(x+1);

a.resize(n+1);

g.resize(n+1);

fr(i,1,n){

cin>>a[i].x0;

a[i].y0=i;

}

fr(i,1,m){

int u,v;

cin>>u>>v;

g[u].pb(v);

g[v].pb(u);

}

fr(i,1,n){

f[i]=i;

sz[i]=1;

st[i]=0;

}

fr(i,1,x){

cin>>h[i];

}

sort(a.begin()+1,a.end(),cmp);

int cnp=1;

for(int i=x;i>=1;i--){

while(cnp<=n&&a[cnp].x0>h[i]){

st[a[cnp].y0]=1;

if(sz[a[cnp].y0]>=minx){

cnt++;

}

for(int v:g[a[cnp].y0]){

if(st[v]){

upd(a[cnp].y0,v);

}

}

cnp++;

}

as[i]=cnt;

}

fr(i,1,x){

cout<<as[i]<<"\n";

}

}

signed main(){

GG;

int _t=1;

//cin>>_t;

while(_t--){

solve();

}

}

G H K 签到

相关推荐
大梦南柯2 小时前
第一次作业
算法
iAkuya2 小时前
(leetcode)力扣100 71字符串解码(栈(两种)||递归)
windows·算法·leetcode
重生之后端学习2 小时前
105. 从前序与中序遍历序列构造二叉树
java·数据结构·后端·算法·深度优先
样例过了就是过了2 小时前
LeetCodere热题100 最小覆盖子串
数据结构·算法·leetcode
追随者永远是胜利者2 小时前
(LeetCode-Hot100)10. 正则表达式匹配
java·算法·leetcode·go
We་ct2 小时前
LeetCode 146. LRU缓存:题解+代码详解
前端·算法·leetcode·链表·缓存·typescript
烟花落o2 小时前
【数据结构系列03】链表的回文解构、相交链表
数据结构·算法·链表·刷题
追随者永远是胜利者2 小时前
(LeetCode-Hot100)17. 电话号码的字母组合
java·算法·leetcode·职场和发展·go
不想看见4042 小时前
Shortest Bridge -- 广度优先搜索 --力扣101算法题解笔记
算法·leetcode·宽度优先