The 2021 ICPC Asia Regionals Online Contest (I)

A

线段树 + 二分

线段树维护结束时间,二分查找合适的结点,找不到则执行下一个询问
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> PII;

const int N = 100010;

PII p[N];
int cnt[N];

struct node{
	int l,r;
	ll min_et;
}tr[N*4];

void pushup(int u){
	tr[u].min_et=min(tr[u<<1].min_et,tr[u<<1|1].min_et);
}

void build(int u,int l,int r){
	tr[u]={l,r};
	if(l==r) return ;
	
	int mid=l+r>>1;
	build(u<<1,l,mid);
	build(u<<1|1,mid+1,r);
}

void update(int u,int pos,int v){
	if(tr[u].l==pos&&tr[u].r==pos) tr[u].min_et=v;
	else{
		int mid=tr[u].l+tr[u].r>>1;
		if(pos<=mid) update(u<<1,pos,v);
		else update(u<<1|1,pos,v);
		pushup(u);
	}
}

ll query(int u,int l,int r){
	if(tr[u].l>=l&&tr[u].r<=r) return tr[u].min_et;
	
	int mid=tr[u].l+tr[u].r>>1;
	ll res=1e18;
	if(l<=mid) res=min(res,query(u<<1,l,r));
	if(r>mid) res=min(res,query(u<<1|1,l,r));
	
	return res;
}

bool cmp(PII a,PII b){
	if(a.first==b.first) return a.second<b.second;
	return a.first>b.first;
}

int main(){
	int k,n;  
	cin>>k>>n;
	
	build(1,0,k-1);
	
	for(int i=0;i<n;i++){
		int x,y;
		cin>>x>>y;
		
		if(i<=k-1) cnt[i]++,update(1,i,x+y);
		else{
			if(tr[1].min_et>x) continue;
			
			int p=i%k,l,r;
			
			if(query(1,p,k-1)<=x) l=p,r=k-1;
			else if(p>=1&&query(1,0,p-1)<=x) l=0,r=p-1;		
			
			while(l<r){
				int mid=l+r>>1;
				if(query(1,l,mid)<=x) r=mid;
				else if(query(1,mid+1,r)<=x) l=mid+1; 
			}
			
			if(query(1,l,l)<=x)  cnt[l]++,update(1,l,x+y);		
		}	
	}
	
	for(int i=0;i<k;i++) p[i]={cnt[i],i};
	
	sort(p,p+k,cmp);
	
	cout<<p[0].second;
	for(int i=1;i<k;i++) {
		if(p[i].first==p[i-1].first) cout<<" "<<p[i].second;
		else break;
	}
	
	return 0;
} 

D

排序 + 线段树

区间修改
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e5+10;

struct node{
	int l,r;
	ll sum;
	int lazy;
	int minv;
}tr[N*4];
struct nope{
	int l,r,w;
	bool operator < (const nope &x) const{
		return w>x.w;
	} ;
}p[N];

void pushdown(int u){
	node &rt=tr[u],&le=tr[u<<1],&ri=tr[u<<1|1];
	if(rt.lazy){
		le.lazy=ri.lazy=rt.lazy;
		le.minv=ri.minv=rt.lazy;
		ll w=rt.lazy;
		le.sum=(ll)w*(le.r-le.l+1);
		ri.sum=(ll)w*(ri.r-ri.l+1);
		rt.lazy=0;
	}
}

void pushup(int u){
	tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
	tr[u].minv=min(tr[u<<1].minv,tr[u<<1|1].minv);
}

void build(int u,int l,int r){
	 tr[u]={l,r,0,0,0};
	 if(l==r) return ;
	 
	 int mid=l+r>>1;
	 build(u<<1,l,mid);
	 build(u<<1|1,mid+1,r);
}

void update(int u,int l,int r,int v){
	if(tr[u].l>=l&&tr[u].r<=r){
		tr[u].lazy=tr[u].minv=v;
		tr[u].sum=(ll)(tr[u].r-tr[u].l+1)*v;
	}
	else{
		pushdown(u);
		int mid=tr[u].l+tr[u].r>>1;
		if(l<=mid) update(u<<1,l,r,v);
		if(r>mid) update(u<<1|1,l,r,v);
		pushup(u);
	}
}

int main(){
	int T; scanf("%d",&T);
	
	for(int ii=1;ii<=T;ii++) {
		int n,m; scanf("%d%d",&n,&m);
		
		build(1,1,n-1);  // n 个点  n-1 条边 
		
		ll ans=0;
		for(int i=0;i<m;i++){ 
		    int l,r,w; scanf("%d%d%d",&l,&r,&w);
			p[i]={l,r,w};
			ans+=(ll)(r-l+1)*(r-l)/2*w;
		}
		
		sort(p,p+m);
		
		for(int i=0;i<m;i++) update(1,p[i].l,p[i].r-1,p[i].w);  // [l,r] 中 r 没有 出边,更新的是有出边的点  
		
		printf("Case #%d: ",ii);
		
		if(!tr[1].minv) printf("Gotta prepare a lesson");
		else printf("%lld",ans-tr[1].sum) ;
		
		if(ii!=T)	puts("");	
	}
	
	return 0;
} 

F

二维几何

#include <bits/stdc++.h>

using namespace std;

double pf(double x){
	return x*x;
}

int main(){
	int T; cin>>T;
	
	for(int i=1;i<=T;i++){
		double a,b,R;
		cin>>a>>b>>R;
		
		printf("Case #%d: ",i);
		if(b>=R){
			double d=sqrt(pf(a)+pf(b-R))*2-R;
			printf("%.2f",d);
		}
		else  printf("%.2f",2*a-R);
        
        if(i!=T) puts("");
	}
	
	return 0;
} 

I

随便

#include <bits/stdc++.h>

using namespace std;

int a[100010];

int main(){
	string line;
	getline(cin,line);
	
	stringstream ss(line);
	
	int x,t=0;
	while(ss>>x)   a[t++]=x;
	
	sort(a,a+t);
	
	int A,R;  cin>>A>>R;
	
	int l=lower_bound(a,a+t,A-R)-a;
	int r=upper_bound(a,a+t,A+R)-a;
	
	bool op=false;
	for(int i=r-1;i>=l;i--) op=true,cout<<a[i]<<" ";
	
	if(!op) puts("");
	
	return 0;
} 

K

vector 模拟

#include <bits/stdc++.h>

using namespace std;

vector<int>v[100010];

int main(){
	int T; cin>>T;
	
	for(int i=1;i<=T;i++){
		int n,m; cin>>n>>m;
		
		for(int ii=1;ii<=n;ii++){
			int D; cin>>D;
			v[ii].clear();
			for(int j=1;j<=D;j++) {	int x;  cin>>x;  v[ii].push_back(x); } 
		}
		
		printf("Case #%d: \n",i);
		
		while(m--){
			int s,l; cin>>s>>l;
			
			int t=0;
			for(int ii=1;ii<=l;ii++) {
				int k; cin>>k;
			    if(k<=v[s].size()) s=v[s][k-1];
			    else t=1;
			}
			
			if(t) printf("Packet Loss");
			else cout<<s;
			
			if(m) puts("");
		}
		
		if(i!=T) puts("");
	}
	
	return 0;
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值