HZOI20190818 25 analog solution to a problem

Questions surface: https://www.cnblogs.com/Juve/articles/11372379.html

A: String

In fact, water is the number CATALAN title. . .

And the grid as a hair: https://www.cnblogs.com/Juve/p/11222358.html

#include<iostream>
#include<cstdio>
#include<cstring>
#define mod 20100403
#define int long long
using namespace std;
int n,m,ans=0;
int q_pow(int a,int b,int p){
	int res=1;
	while(b){
		if(b&1) res=(res*a)%p;
		a=(a*a)%p;
		b>>=1;
	}
	return res%p;
}
int fac(int n){
	if(n==1||n==0) return 1;
	int res=1;
	for(int i=2;i<=n;i++)
		res=(res*i)%mod;
	return res%mod;
}
int inv(int n){
	if(n==0) return 1;
	return q_pow(fac(n),mod-2,mod)%mod;
}
int C(int n,int m){
	if(n==m) return 1;
	if(n<m) return 0;
	return fac(n)*inv(m)%mod*inv(n-m)%mod;
}
signed main(){
	scanf("%lld%lld",&n,&m);
	ans=C(n+m,n)*q_pow(m+1,mod-2,mod)%mod*(n-m+1)%mod;
	printf("%lld\n",ans%mod);
	return 0;
}

B: Crow flying water

Crow drink is "time to drink a certain drink", so it does not matter and DP decision-making.

Direct simulation complexity is O ( n- m )

Each tank in accordance with the number of times you can drink (that is, how many times to drink water, drink the water level drops to less than) ascending sort order processing.

Obviously if the drink in front of the tank n times, the back of the tank also drink at least n times, the nature of this very useful.

The above can be introduced by this sentence: If the end of crows flew through the ranks from the current location will be a drink of water tank k, and the number of the current tank can drink the x> = k, then after the tank will not be in this is an empty drink.

1, each tank begins enumeration (enumeration to the tank when the remaining number of times smaller in front of tanks has been finished. Alternatively as will be appreciated, discard the front cylinder, the greedy drink.)

2, the maintenance tank with Fenwick tree ID, the ID inquiry from the tank to the current (original) as well as the number of tanks in the n-th drink water tanks, if the remaining number of the current cylinder is> = the number of remaining cylinders , update frequency and skip directly to the next round.

3, after several second operation, the current remaining number of cylinders <= remaining number of cylinders, in this case an array of binary tree "remainder", i.e., a drink and a certain position, this cylinder out of water.

4, the current standard cylinder is empty, the next enumerated a tank.

Surface looked high complexity, in fact, the number of water does not exceed a maximum number of cylinders that can drink (water because each cylinder are all lowered with water), while the number of simulation operations does not exceed m (m drink up wheel), the complexity is acceptable.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define int long long
#define MAXN 100005
using namespace std;
int n,m,x;
struct node{
	int d,a,id,tim;
	friend bool operator < (node a,node b){
		return a.tim<b.tim;
	}
}w[MAXN];
struct BITREE{
	int c[MAXN];
	int lowbit(int x){
		return x&(-x);
	}
	void update(int pos,int val){
		for(int i=pos;i<=n;i+=lowbit(i))
			c[i]+=val;
	}
	int query(int pos){
		int res=0;
		for(int i=pos;i;i-=lowbit(i))
			res+=c[i];
		return res;
	}
}BIT;
int last=0,now=0,ans=0;
int find(int x){
	int res=last,l=last,r=n;
	while(l<=r){
		int mid=(l+r)>>1;
		if(BIT.query(mid)-BIT.query(last)<=x)
			res=mid,l=mid+1;
		else r=mid-1;
	}
	return res;
}
signed main(){
	scanf("%lld%lld%lld",&n,&m,&x);
	for(int i=1;i<=n;i++){
		scanf("%lld",&w[i].d);
		w[i].id=i;
	}
	for(int i=1;i<=n;i++){
		scanf("%lld",&w[i].a);
		w[i].tim=(x-w[i].d)/w[i].a+1;
		BIT.update(w[i].id,1);
	}
	sort(w+1,w+n+1);
	for(int i=1;i<=n;i++){
		if(w[i].tim<ans){
			BIT.update(w[i].id,-1);
			continue;
		}
		while(now<m){
			int sum=BIT.query(n)-BIT.query(last);
			if(sum+ans>w[i].tim) break;
			ans+=sum;
			last=0;
			now++;
		}
		if(now>=m) break;
		last=find(w[i].tim-ans);
		ans=w[i].tim;
		BIT.update(w[i].id,-1);
	}
	printf("%lld\n",ans);
	return 0;
}

C: The camel door King's Treasure

%% AlpaCa alpaca brother

Scary face problems, but a water problem

First you mention the input from the dry construction in the map

Construction Plan is very sb

I defined two vector, each row of memory palaces coordinates and type of each column

Then scan each line, a horizontal search to put it days gate lines and each of the even side palace, other same token,

Then just before the bombings and the same,

tarjan point reduction, and then run on the newly FIG topology, find the longest chain of FIG new

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#define MAXK 1000005
#define re register
using namespace std;
int n,m,k,ans=0,res[MAXK];
struct node{
	int opt,id,x,y;
};
vector<node>h[MAXK],l[MAXK];
struct EDGE{
	int to,nxt;
}e[MAXK<<2];
int head[MAXK],cnt=0;
inline void add(re int u,re int v){
	cnt++,e[cnt].to=v,e[cnt].nxt=head[u],head[u]=cnt;
}
int dfn[MAXK],low[MAXK],sta[MAXK],top=0,dfs_order=0,tot=0,belong[MAXK],siz[MAXK];
bool in_sta[MAXK];
inline void tarjan(re int x){
	dfn[x]=low[x]=++dfs_order;
	sta[++top]=x;
	in_sta[x]=1;
	for(re int i=head[x];i;i=e[i].nxt){
		re int y=e[i].to;
		if(!dfn[y]){
			tarjan(y);
			low[x]=min(low[x],low[y]);
		}
		else if(in_sta[y]) low[x]=min(low[x],dfn[y]);
	}
	if(dfn[x]==low[x]){
		tot++;
		re int y;
		do{
			y=sta[top--];
			in_sta[y]=0;
			belong[y]=tot;
			siz[tot]++;
		}while(y!=x);
	}
}
int to[MAXK<<2],nxt[MAXK<<2],pre[MAXK],sum=0;
inline void ADD(re int u,re int v){
	sum++,to[sum]=v,nxt[sum]=pre[u],pre[u]=sum;
}
int in_deg[MAXK];
queue<int>q;
int main(){
	scanf("%d%d%d",&k,&n,&m);
	for(re int i=1,u,v,opt;i<=k;i++){
		scanf("%d%d%d",&u,&v,&opt);
		h[u].push_back((node){opt,i,u,v});
		l[v].push_back((node){opt,i,u,v});
	}
	for(re int i=1;i<=n;i++){
		re int N=h[i].size();
		for(re int j=0;j<N;j++){
			node t=h[i][j];
			if(t.opt==1){
				for(re int p=0;p<N;p++){
					if(t.id==h[i][p].id) continue;
					add(t.id,h[i][p].id);
				}
			}else if(t.opt==2){
				re int M=l[t.y].size();
				for(re int p=0;p<M;p++){
					if(t.id==l[t.y][p].id) continue;
					add(t.id,l[t.y][p].id);
				}
			}else{
				for(re int p=max(1,t.x-1);p<=min(n,t.x+1);p++){
					re int r=h[p].size();
					for(re int q=0;q<r;q++){
						if(h[p][q].id==t.id) continue;
						if(abs(t.y-h[p][q].y)>1) continue;
						add(t.id,h[p][q].id);
					}
				}
			}
		}
	}
	for(re int i=1;i<=k;i++){
		if(!dfn[i]) tarjan(i);
	}
	for(re int i=1;i<=k;i++){
		for(re int j=head[i];j;j=e[j].nxt){
			re int y=e[j].to;
			if(belong[y]!=belong[i]){
				ADD(belong[i],belong[y]);
				in_deg[belong[y]]++;
			}
		}
	}
	for(re int i=1;i<=tot;i++){
		res[i]=siz[i];
		if(!in_deg[i]) q.push(i);
	}
	while(!q.empty()){
		re int x=q.front();
		q.pop();
		in_deg[x]--;
		for(re int i=pre[x];i;i=nxt[i]){
			re int y=to[i];
			in_deg[y]--;
			res[y]=max(res[y],res[x]+siz[y]);
			ans=max(res[y],ans);
			if(!in_deg[y]) q.push(y);
		}
	}
    //for(re int i=1;i<=tot;i++)
	//	ans=max(res[i],ans);
	printf("%d\n",ans);
	return 0;
}

 

Guess you like

Origin www.cnblogs.com/Juve/p/11372389.html