• [NOIP11.1模拟赛]补番报告


    Preface

    昨天开始补某科学的超电磁炮S 感觉今天就好了点,炮姐赛高

    T1 一开始一直想欧拉定理&ex欧拉定理,结果估计70分,数组开小了GG,看了正解发现是我学傻了

    T2 一看就是数据结构,之前某次模拟还做过区间位运算线段树但是不敢打,只敲了个前缀和预计50结果有个地方没膜GG

    T3 想了蛮久,很有意思的一道题目,考场上画了图发现我们可以将放坐标的那个点看成树根,这样它覆盖了一条近似链的玩意,想搞波DP发现不会,于是打了个骗分的玩意,就是我猜和节点的儿子个数有关,我直接用儿子个数除2向上取整结果...OJ上15,source里30.发现ZZ地没判点的情况,然后发现更ZZ的是我特意判了链的情况,但是我输出的是0

    10分就这么走了GG

    T1 pow

    学傻了的我一直想欧拉定理...结果solution告诉你只要会快速幂就可以A这题了

    a既然是定值我们就分块打表啊

    由于b最大是1e12,按1e6拆分.

    预处理出({a^1}... {a^{1e6}}),丢进一个数组,在预处理出(a^{i imes 1e6}),丢进另外一个数组

    这样所有的b都能拼出来了

    还是比较妙的,这告诉我们有的时候去搞旧算法不如想新trick

    代码

    const int maxn=1000005;
    const int inf = 0x7fffffff;
    ll a,q,k;
    ll b,l,m,c,p;
    ll pre[maxn][2],sum[10000005];
    inline ll ksm(ll aa,ll cc){
    	ll ans=1;
    	while(cc){
    		if(cc&1)ans=ans*a%p;
    		aa=aa*aa%p;
    		cc=cc>>1;
    	}
    	return ans;
    }
    int main(){
    	FI(pow)FO(pow)
    	read(a),read(p),read(q),read(k);
    	read(b),read(l),read(m),read(c);
    	pre[0][0]=1;
    	for(ri i=1;i<=1000000;i++){
    		pre[i][0]=pre[i-1][0]*a%p;
    	}
    	pre[1][1]=pre[1000000][0];
    	for(ri i=2;i<=1000000;i++){
    		pre[i][1]=pre[i-1][1]*pre[1][1]%p;
    	}
    	for(ri i=1;i<=q;i++){
    		b=(b*m+c)%l;
    		if(b<=1000000)sum[i]=sum[i-1]^pre[b][0];
    		else {
    			ll id=b/1000000;
    			sum[i]=sum[i-1]^((pre[b%1000000][0]*pre[id][1])%p);
    		}
    	}
    	int kk=k;
    	while(kk<=q){
    		printf("%lld
    ",sum[kk]);
    		kk+=k;
    	}
    	return 0;
    }
    
    

    T2 seg

    英文是seg 中文是tree 就是告诉你用线段树(segment tree)啦

    对于区间按位与操作,类比区间取膜的时间复杂度分析(给学弟讲过结果自己还忘了)

    每个数最多操作31次,n只有1e5,因此是资瓷的

    我们只要维护一个区间按位或判断需不需要修改就好了,其余情况暴力递归修改

    2操作就trival了,会线段树的都会

    3操作也比较正常,你可以先思考部分分怎么拿,你把这个期望平方和(实际上这个式子就是(sum_{i=l}^r (a_i+a_j)^2 (j=l,l+1...r)))大力展开

    发现维护一个区间平方和和区间和就好了

    然后有个神坑的地方

    就是在判断是否要按位与时的位运算的优先级

    if((or_sum[now]&(~dta))==0)return ;

    if(or_sum[now]&(~dta)==0)return ;

    请您判断上面哪个是对的

    答案是第一个,但是你写第二个不会对答案正确性产生影响,但是每次它都会递归下去修改使得时间复杂度大大提高

    可见位运算优先级之低

    代码

    const int maxn=100005;
    const int inf=0x7fffffff;
    const int P=998244353;
    int a[maxn],n,q;
    ll sum[maxn<<2];
    int eq_sum[maxn<<2];
    int or_sum[maxn<<2];
    inline void up(int now){
    	sum[now]=sum[now<<1]+sum[now<<1|1];
    	eq_sum[now]=(eq_sum[now<<1]+eq_sum[now<<1|1]);
    	if(eq_sum[now]>P)eq_sum[now]-=P;
    	or_sum[now]=or_sum[now<<1]|or_sum[now<<1|1];
    	return ;
    }
    void build(int now,int l,int r){	
    	if(l==r){
    		or_sum[now]=sum[now]=a[l];
    		eq_sum[now]=1ll*a[l]*a[l]%P;
    		return ;
    	}
    	int mid=(l+r)>>1;
    	build(now<<1,l,mid);
    	build(now<<1|1,mid+1,r);
    	up(now);return ;
    }
    int dta,t,L,R;
    void update(int now,int l,int r){
    	if((or_sum[now]&(~dta))==0)return ;//运算符顺序!!! 
    	if(l==r){
    		a[l]=a[l]&dta;
    		or_sum[now]=sum[now]=a[l];
    		eq_sum[now]=1ll*a[l]*a[l]%P;
    		return ;
    	}
    	int mid=(l+r)>>1;
    	if(L<=mid)update(now<<1,l,mid);
    	if(mid<R)update(now<<1|1,mid+1,r);
    	up(now);return ;
    }
    ll ans1=0,ans2=0;
    void query(int now,int l,int r){
    	if(L<=l&&r<=R){
    		ans1+=sum[now];
    		ans2=(ans2+eq_sum[now]);
    		if(ans2>P)ans2-=P;
    		return ;
    	}
    	int mid=(l+r)>>1;
    	if(L<=mid)query(now<<1,l,mid);
    	if(mid<R)query(now<<1|1,mid+1,r);
    	return ;
    }
    int main(){
    	int x,y,opt;
    	FO(seg)
    	//freopen("seg6.in","r",stdin);
    	//freopen("wtf.out","w",stdout);
    	read(n);
    	for(ri i=1;i<=n;i++)read(a[i]);
    	build(1,1,n);
    	read(q);
    	while(q--){
    		read(opt),read(L),read(R);
    		ans1=ans2=0;
    		if(opt==1){
    			read(dta);
    			update(1,1,n);
    		}
    		if(opt==2){
    			query(1,1,n);
    			printf("%lld
    ",ans1);
    		}
    		if(opt==3){
    			query(1,1,n);
    			ans1=ans1%P;
    			printf("%lld
    ",(((ans2<<1)%P*(R-L+1)%P+(ans1<<1)*ans1%P))%P);
    		}
    	}
    	return 0;
    }
    
    

    T3 beacon

    一道Topcoder上有趣的题目

    我是这么想的,除了一点之外的情况,答案肯定是大与等于1的,我们不妨先钦定一个点,在上面放一个信标,然后以它为根遍历整棵树,显然此时深度相同的点都是非法的

    考虑这种情况:有两个兄弟叶节点,那么它们此时是非法的,显然在除这两个叶节点之外的任何一点放置信标这两点还是非法的(它们的深度还是相同),所以我们必须在这两个叶子节点之一放一个信标

    稍微拓展一下:假若有三个兄弟叶节点,那么类似的发现你必须在三个叶节点中放两个信标才可以;于是归纳假设发现对于n个兄弟叶节点你必须在之中放n-1个信标

    那么对于不是叶节点的点呢?你会发现这时候它们似乎都已经是合法的了

    除了链的情况,链的情况下由于最底端只有一个叶子节点不会统计答案,但是实际上你会发现链实际上整体就可以看做一个叶节点处理.

    于是按照上面的步骤(O(N^2))就好了

    满分做法看不懂,这里给出题解,不知哪位大佬可以帮忙解释一下

    如何做到 O(n)? 我们先特判链的情况答案为 1, 然后找到任意一个度数大于 2 的节点, 可以证
    明这个点一定不需要放置信标. 于是以这个点作根 O(n) 的贪心即可. 证明如下:
    深度相同的点对证明同上, 只考虑深度不同的点对. 如果它们在一颗子树中, 由于度数大于 2 所
    以一定有另一颗子树的一个信标把他们区分开. 如果在不同的子树中, 有两种情况:
    一个在没放信标的子树中, 一个在放了的子树中. 显然还存在另一个子树放了信标, 由于深度不
    同他们会被这个信标区分开.
    两个都在放了信标的子树中. 如果根的度数大于 3 则同上. 度数等于 3 时, 如果他们没有被区分
    开, 一定是他们先汇集到了一个节点上, 然后走到同一个信标上. 这个点一定是一条奇链的中点, 且
    不是根 (由于深度不同), 是在两个子树之一中唯一的. 那么他们走到另一个信标就一定有一个点走
    了冤枉路, 既另一个信标可以区分出他们

    70分代码

    const int maxn=1000005;
    const int inf=0x7fffffff;
    int n;
    struct Edge{
    	int ne,to;
    }edge[maxn<<1];
    int h[maxn],num_edge=1;
    inline void add_edge(int f,int to){
    	edge[++num_edge].ne=h[f];
    	edge[num_edge].to=to;
    	h[f]=num_edge;
    }
    int ans=inf,sum=0;
    bool is_lef[maxn],on_chain[maxn];
    void dfs(int now,int fa){
    	int v,cnt=0,tot=0;
    	is_lef[now]=0,on_chain[now]=0;
    	for(ri i=h[now];i;i=edge[i].ne){
    		v=edge[i].to;
    		if(v==fa)continue;
    		is_lef[now]=1,tot++;
    		dfs(v,now);
    		if(!is_lef[v]||on_chain[v])cnt++;
    	}
    	if(tot==1&&cnt==1)on_chain[now]=1;
    	if(cnt>1)sum+=cnt-1;
    	return ;
    }
    int deg[maxn];
    int main(){
    	int x,y;
    	//FO(beacon)
    	read(n);
    	if(n==1){puts("0");return 0;}
    	for(ri i=1;i<n;i++){
    		read(x),read(y);
    		add_edge(x,y),add_edge(y,x);
    	}
    	for(ri rt=1;rt<=n;rt++){
    		sum=0;
    		dfs(rt,0);
    		ans=min(ans,sum+1);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    echarts 折线图(移动端)X轴显示不全
    文字超出省略号类型
    逻辑运算为true
    13年省赛总结
    PyCharm专业版破解教程
    django之定义统一返回数据格式与GET/POST装饰器
    Xmind8破解教程
    django之mysqlclient安装
    django之“static”全局设置
    django之集成第三方支付平台PaysAPI与百度云视频点播服务接入
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/9892335.html
Copyright © 2020-2023  润新知