• 测试「2020牛客NOIP赛前集训营-提高组(第五场)」


    T1

    签到题。

    ( ext{Code}:)

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #define Rint register int
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long lxl;
    const int maxn=1e6+5;
    
    template <typename T>
    inline void read(T &x)
    {
    	x=0;T f=1;char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	x*=f;
    }
    
    int n;
    lxl ans;
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("A.in","r",stdin);
    #endif
    	read(n);
    	for(int i=1;i<=n;++i)
    		for(int j=i<<1;j<=n;j+=i)
    			ans+=(n-j)/j;
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    T2

    找到 (T)(S) 中出现的所有位置计数即可。

    ( ext{Code}:)

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #define Rint register int
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long lxl;
    const int maxn=1e7+5;
    const lxl mod=998246353;
    const lxl p=233;
    
    template <typename T>
    inline void read(T &x)
    {
    	x=0;T f=1;char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	x*=f;
    }
    
    int n,k;
    char s[maxn],t[maxn];
    lxl hshs[maxn],hsht,P[maxn],ans;
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("B.in","r",stdin);
    #endif
    	read(n),read(k);
    	scanf(" %s %s",s+1,t+1);
    	P[0]=1;
    	for(int i=1;i<=n;++i)
    		hshs[i]=(hshs[i-1]*p+s[i])%mod,P[i]=(P[i-1]*p)%mod;
    	for(int i=1;i<=k;++i) hsht=(hsht*p+t[i])%mod;
    	int las=0;
    	for(int i=k;i<=n;++i)
    		if((hshs[i]-hshs[i-k]*P[k]%mod+mod)%mod==hsht)
    		{
    			if(las) ans+=1ll*(las-k+1)*(i-las);
    			las=i;
    		}
    	if(las) ans+=1ll*(las-k+1)*(n-las+1);
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    T3

    将所有数丢到可持久化Trie上,然后差分求第 (k) 大即可。因为这道题字符串长度不一致,所以调了1h+。

    然后最后30min发现可以直接预处理出所有数字的字典序,然后主席树维护,花了不到20min就调出来了/fad,赛后发现这才是正解。

    ( ext{Code}:)

    可持久化Trie:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #define ONLINE_JUDGE
    #define Rint register int
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long lxl;
    const int maxn=1e5+5;
    
    template <typename T>
    inline void read(T &x)
    {
    	x=0;T f=1;char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	x*=f;
    }
    
    int n,q;
    
    namespace Trie
    {
    	int tot,rt[maxn];
    	int ch[maxn<<4][10],siz[maxn<<4],idx[maxn<<4];
    	inline void insert(int u,int x,int tmp)
    	{
    		static int buf[10],top;
    		top=0;int d=x;
    		while(d) buf[++top]=d%10,d/=10;
    		for(int i=top;i>=1;--i)
    		{
    			int c=buf[i];
    			siz[u]=siz[tmp]+1;
    			idx[u]=idx[tmp];
    			for(int j=0;j<=9;++j) ch[u][j]=ch[tmp][j];
    			ch[u][c]=++tot;
    			u=ch[u][c];
    			tmp=ch[tmp][c];
    		}
    		siz[u]=siz[tmp]+1;
    		for(int j=0;j<=9;++j) ch[u][j]=ch[tmp][j];
    		idx[u]=x;
    	}
    	inline int query(int pl,int pr,int k)
    	{
    		if(idx[pr]-idx[pl]!=0&&k==1) return idx[pr];
    		k-=(idx[pr]-idx[pl]!=0);
    		for(int i=0;i<=9;++i)
    			if(siz[ch[pr][i]]-siz[ch[pl][i]]<k)
    				k-=siz[ch[pr][i]]-siz[ch[pl][i]];
    			else return query(ch[pl][i],ch[pr][i],k);
    		return -1;
    	}
    }
    using Trie::rt;
    using Trie::tot;
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("C.in","r",stdin);
    	freopen("C.out","w",stdout);
    #endif
    	read(n),read(q);
    	for(int i=1,x;i<=n;++i)
    	{
    		read(x);
    		Trie::insert(rt[i]=++tot,x,rt[i-1]);
    	}
    	int l,r,k;
    	while(q--)
    	{
    		read(l),read(r),read(k);
    		printf("%d
    ",Trie::query(rt[l-1],rt[r],k));
    	}
    	return 0;
    }
    

    主席树:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #define ONLINE_JUDGE
    #define Rint register int
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long lxl;
    const int maxn=1e5+5;
    
    #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    char buf[1<<21],*p1=buf,*p2=buf;
    template <typename T>
    inline void read(T &x)
    {
    	x=0;T f=1;char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	x*=f;
    }
    
    int n,q;
    int val[maxn],a[maxn];
    
    struct number
    {
    	int dig[10],len,x;
    	number(int x):x(x)
    	{
    		len=0;
    		while(x) dig[++len]=x%10,x/=10;
    		for(int i=1;(1<<i)<=len;++i)
    			swap(dig[i],dig[len-i+1]);
    	}
    	number(){}
    	inline bool operator < (const number &T)const
    	{
    		int L=min(len,T.len);
    		for(int i=1;i<=L;++i)
    			if(dig[i]!=T.dig[i]) return dig[i]<T.dig[i];
    		return len<T.len;
    	}
    }num[maxn];
    
    namespace Segment_Tree
    {
    	int tot;
    	int sum[maxn<<5],ch[maxn<<5][2];
    	void modify(int &p,int l,int r,int ps,int tmp)
    	{
    		p=++tot;
    		sum[p]=sum[tmp]+1;
    		ch[p][0]=ch[tmp][0];ch[p][1]=ch[tmp][1];
    		if(l==r) return;
    		int mid=(l+r)>>1;
    		if(ps<=mid) modify(ch[p][0],l,mid,ps,ch[tmp][0]);
    		else modify(ch[p][1],mid+1,r,ps,ch[tmp][1]);
    	}
    	int query(int pl,int pr,int l,int r,int k)
    	{
    		if(l==r) return (sum[pr]-sum[pl]&&k==1)?num[l].x:-1;
    		int mid=(l+r)>>1;
    		if(sum[ch[pr][0]]-sum[ch[pl][0]]>=k)
    			return query(ch[pl][0],ch[pr][0],l,mid,k);
    		else return query(ch[pl][1],ch[pr][1],mid+1,r,k-(sum[ch[pr][0]]-sum[ch[pl][0]]));
    	}
    }
    int rt[maxn];
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("C.in","r",stdin);
    	freopen("baoli.out","w",stdout);
    #endif
    	read(n),read(q);
    	for(int i=1;i<=n;++i)
    	{
    		read(a[i]);
    		num[i]=number(a[i]);
    	}
    	sort(num+1,num+n+1);
    	for(int i=1;i<=n;++i)
    		val[num[i].x]=i;
    	for(int i=1;i<=n;++i)
    		Segment_Tree::modify(rt[i],1,n,val[a[i]],rt[i-1]);
    	int l,r,k;
    	while(q--)
    	{
    		read(l),read(r),read(k);
    		printf("%d
    ",Segment_Tree::query(rt[l-1],rt[r],1,n,k));
    	}
    	return 0;
    }
    

    T4

    容易发现这是一个树形结构,每个圆向包含它的最小的圆连边,现在问题就是如何找到这个圆。

    用扫描线从左往右扫,用set记录扫描线与圆的交点,按纵坐标排序。每次新加入一个圆时,查找它上面第一个圆弧,若这个圆弧是上半圆弧,那么这个圆弧对应的圆就是这个圆的父亲,否则就是它的兄弟。

    建完树求LCA即可。

    ( ext{Code}:)

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <set>
    #define Rint register int
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long lxl;
    const int maxn=1e5+5;
    
    template <typename T>
    inline void read(T &x)
    {
    	x=0;T f=1;char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	x*=f;
    }
    
    struct edge
    {
    	int u,v,next;
    	edge(int u,int v,int next):u(u),v(v),next(next){}
    	edge(){}
    }e[maxn];
    
    int head[maxn],ecnt;
    
    inline void add(int u,int v)
    {
    	e[ecnt]=edge(u,v,head[u]);
    	head[u]=ecnt++;
    }
    
    int n,q;
    
    namespace Tree
    {
    	int dep[maxn],fa[maxn],top[maxn],son[maxn],siz[maxn];
    	void dfs1(int u)
    	{
    		dep[u]=dep[fa[u]]+1;
    		siz[u]=1;
    		for(int i=head[u];~i;i=e[i].next)
    		{
    			int v=e[i].v;
    			dfs1(v);
    			siz[u]+=siz[v];
    			if(siz[v]>siz[son[u]]) son[u]=v;
    		}
    	}
    	void dfs2(int u,int t)
    	{
    		top[u]=t;
    		if(!son[u]) return;
    		dfs2(son[u],t);
    		for(int i=head[u];~i;i=e[i].next)
    		{
    			int v=e[i].v;
    			if(v==son[u]) continue;
    			dfs2(v,v);
    		}
    	}
    	inline int LCA(int a,int b)
    	{
    		for(;top[a]!=top[b];dep[top[a]]>dep[top[b]]?a=fa[top[a]]:b=fa[top[b]]);
    		return dep[a]<dep[b]?a:b;
    	}
    }
    using Tree::dep;
    using Tree::fa;
    
    struct circle
    {
    	int x,y,r;
    	circle(int x,int y,int r):x(x),y(y),r(r){}
    	circle(){}
    }cir[maxn];
    
    struct Time
    {
    	int x,id,type;
    	Time(int x,int id,int type):x(x),id(id),type(type){}
    	Time(){}
    	inline bool operator < (const Time &T)const
    	{
    		return x<T.x;
    	}
    }t[maxn<<1];
    int tcnt;
    
    int now;
    
    struct node
    {
    	int id,type;
    	node(int id,int type):id(id),type(type){}
    	node(){}
    	inline double calcu()const
    	{
    		return (double)cir[id].y+
    		(double)type*sqrt((double)cir[id].r*cir[id].r-(double)(cir[id].x-now)*(cir[id].x-now));
    	}
    	inline bool operator < (const node &T)const
    	{
    		return id==T.id?type<T.type:calcu()<T.calcu();
    	}
    };
    
    set<node> s;
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("D.in","r",stdin);
    	freopen("D.out","w",stdout);
    #endif
    	read(n);
    	for(int i=1,x,y,r;i<=n;++i)
    	{
    		read(x),read(y),read(r);
    		cir[i]=circle(x,y,r);
    		t[++tcnt]=Time(x-r,i,1);
    		t[++tcnt]=Time(x+r,i,-1);
    	}
    	sort(t+1,t+tcnt+1);
    	for(int i=1;i<=tcnt;++i)
    	{
    		now=t[i].x;
    		if(t[i].type==1)
    		{
    			auto it=s.upper_bound(node(t[i].id,1));
    			if(it==s.end()) fa[t[i].id]=n+1;
    			else if(it->type==1) fa[t[i].id]=it->id;
    			else fa[t[i].id]=fa[it->id];
    			s.insert(node(t[i].id,1));
    			s.insert(node(t[i].id,-1));
    		}
    		else
    		{
    			s.erase(s.find(node(t[i].id,1)));
    			s.erase(s.find(node(t[i].id,-1)));
    		}
    	}
    	memset(head,-1,sizeof(head));
    	for(int i=1;i<=n;++i)
    		add(fa[i],i);
    	Tree::dfs1(n+1);
    	Tree::dfs2(n+1,n+1);
    	read(q);
    	int u,v;
    	while(q--)
    	{
    		read(u),read(v);
    		int f=Tree::LCA(u,v);
    		printf("%d
    ",dep[u]+dep[v]-2*dep[f]-(u!=f)-(v!=f));
    	}
    	return 0;
    }
    
  • 相关阅读:
    淘宝客之 API调用实例讲解
    15个哲理小故事
    淘宝客之 淘宝客类目URL获取
    应广大淘宝客支持者 发布CHM API文档一份 鄙视官方没有离线文档
    淘宝客开发知识 开发前准备与基础知识
    富人和穷人间存在的十二个致命差异
    侧边栏
    半颗星星评分
    让DIV动起来
    软件项目开发过程中主要遇到的核心问题小结
  • 原文地址:https://www.cnblogs.com/syc233/p/13889963.html
Copyright © 2020-2023  润新知