2018徐州网络赛F,H,I

只能来划水,只做了3题。

F:队友切的

#include<bits/stdc++.h>
using namespace std;
int line,k,T,ans,x,y,len;
int main()
{
	cin>>T;
	while(T--)
	{
		ans=0;
		scanf("%d",&line);
		map <pair<int,int> ,vector<int> > mp;
		for(int i=1;i<=line;i++)
		{
			scanf("%d",&k);
			for(int j=1;j<=k;j++)
			{
				scanf("%d%d",&x,&y);
				if(!mp[make_pair(x,y)].empty()&&mp[make_pair(x,y)].back() ==i ) continue;
				mp[make_pair(x,y)].push_back(i);
			}
		}
		for(auto it=mp.begin();it!=mp.end();++it)
		{
			vector<int> &v=it->second; 
			if(!v.size()) continue;
			else 
			{
				len = 1;
				for (int i = 1; i < v.size(); ++i) 
				{
					if (v[i]-v[i - 1]==1)len++;
					else 
					{
						ans = max(ans, len);
						len = 1;
					}
				}
				ans = max(ans, len);
			}	
		}
		cout<<ans<<endl;
	}
	return 0;
}
 

H:所求的答案就是从l开始的前缀和,用线段树维护前缀和就行了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 100007  //元素总个数
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
ll Sum[maxn<<2],Add[maxn<<2];//Sum求和,Add为懒惰标记 
ll A[maxn];//存原数组数据下标[1,n] 
ll X[maxn];
ll n,q;
//PushUp函数更新节点信息 ,这里是求和
void PushUp(ll rt){Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1];}

void PushDown(ll rt,ll ln,ll rn){
	//ln,rn为左子树,右子树的数字数量。 
	if(Add[rt]){
		//下推标记 
		Add[rt<<1]+=Add[rt];
		Add[rt<<1|1]+=Add[rt];
		//修改子节点的Sum使之与对应的Add相对应 
		Sum[rt<<1]+=Add[rt]*ln;
		Sum[rt<<1|1]+=Add[rt]*rn;
		//清除本节点标记 
		Add[rt]=0;
	}
}
//Build函数建树 
void Build(ll l,ll r,ll rt){ //l,r表示当前节点区间,rt表示当前节点编号
	if(l==r) {//若到达叶节点 
		Sum[rt]=A[l];//储存数组值 
		return;
	}
	ll m=(l+r)>>1;
	//左右递归 
	Build(l,m,rt<<1);
	Build(m+1,r,rt<<1|1);
	//更新信息 
	PushUp(rt);
}
void Update(ll L,ll R,ll C,ll l,ll r,ll rt){//L,R表示操作区间,l,r表示当前节点区间,rt表示当前节点编号 
	if(L <= l && r <= R){//如果本区间完全在操作区间[L,R]以内 
		Sum[rt]+=C*(r-l+1);//更新数字和,向上保持正确
		Add[rt]+=C;//增加Add标记,表示本区间的Sum正确,子区间的Sum仍需要根据Add的值来调整
		return ; 
	}
	ll m=(l+r)>>1;
	PushDown(rt,m-l+1,r-m);//下推标记
	//这里判断左右子树跟[L,R]有无交集,有交集才递归 
	if(L <= m) Update(L,R,C,l,m,rt<<1);
	if(R >  m) Update(L,R,C,m+1,r,rt<<1|1); 
	PushUp(rt);//更新本节点信息 
} 

ll Query(ll L,ll R,ll l,ll r,ll rt){//L,R表示操作区间,l,r表示当前节点区间,rt表示当前节点编号
	if(L <= l && r <= R){
		//在区间内,直接返回 
		return Sum[rt];
	}
	ll m=(l+r)>>1;
	//下推标记,否则Sum可能不正确
	PushDown(rt,m-l+1,r-m); 
	
	//累计答案
	ll ANS=0;
	if(L <= m) ANS+=Query(L,R,l,m,rt<<1);
	if(R >  m) ANS+=Query(L,R,m+1,r,rt<<1|1);
	return ANS;
} 

int main(){
	scanf("%lld%lld",&n,&q);
	ll temp;
	for(ll i=1;i<=n;++i){
		scanf("%lld",X+i);
		A[i]=A[i-1]+X[i];
	}
	Build(1,n,1);
	ll x,y,z;
	for(ll i=0;i<q;++i){
		scanf("%lld%lld%lld",&x,&y,&z);
		if(x==1){//查询 
			ll count=z-y+1;
			ll ans=Query(y,z,1,n,1);
			if(y==1){
				cout<<ans<<endl; 
			}
			else{
				ans=ans-count*(Query(y-1,y-1,1,n,1));
				cout<<ans<<endl;
			}
			
		}
		else{//修改 
			ll ago=X[y];
			X[y]=z;
			ll change=z-ago;
			Update(y,n,change,1,n,1);
		}
	}
	
	return 0;
}

I:ans是0的时候结果是1,结果导致Wa了12发。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
	int T;
	scanf("%d",&T);
	while (T--)
	{
		int N;
		char ch;
		scanf("%d %c",&N,&ch);
		string s;
		cin >> s;
		ll ans=0;
		for (int i=0; i<N; ++i)
		{
			if(abs((int)(ch-s[i]))!=0)
			{
				ans = (N-i)*2;
				if(abs((int)(ch-s[i]))<10)
				{
					ans--;
				}
				break;
			}
		}
		printf("%lld\n",ans==0?1:ans);
	}
 	return 0; 
}

猜你喜欢

转载自blog.csdn.net/TDD_Master/article/details/82627520