赛时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 签到