zoukankan      html  css  js  c++  java
  • CF1442B Solution

    题目链接

    题解

    什么时候可以执行操作:若想将(a_i)取出到(b)数组中,则(a_{i-1})(a_{i+1})中一定有一项没有出现在(b)数组接下来的元素中,因为要将其删除。

    如何统计答案:假设(a_i=b_j),对于每一个(b_j)有两种可能方案,删除(a_{i-1})(a_{i+1})。易证,在两种方案都可执行时,删除哪一个都是一样的。由排列组合可得,最终的方案总数等于(b)数组中每一项方案数的乘积。

    如何维护(a)数组:由题意需要一个(O(logn))复杂度内插入或删除元素的数据结构,因此可以使用双向链表。

    AC代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=2e5+10,mod=998244353;
    struct node {int l,r,v;} lst[N];//链表
    int id[N],a[N],b[N],qaq[N];//qaq[i]:b数组中第i项的方案数
    //id[i]:值为i的元素在a数组中的下标
    bool qwq[N];//qwq[i]:b数组接下来的元素中是否有i
    void del(int x)
    {
    	lst[lst[x].r].l=lst[x].l; lst[lst[x].l].r=lst[x].r;
    }//删除链表中下表为x的元素
    signed main()
    {
    	int t,n,k;
    	scanf("%lld",&t);
    	while(t--)
    	{
    		scanf("%lld%lld",&n,&k);
            //预处理
    		for(int i=1;i<=n;i++) qwq[i]=0,qaq[i]=0;
    		for(int i=1;i<=n;i++) 
    		{
    			scanf("%lld",&a[i]); 	
    			lst[i].l=i-1; lst[i].r=i+1; 
    			lst[i].v=a[i]; id[a[i]]=i;
    		}
    		lst[0].r=1; lst[n+1].l=n;
    		lst[0].v=lst[n+1].v=0;
    		for(int i=1;i<=k;i++) {scanf("%lld",&b[i]); qwq[b[i]]=1;}
    		qwq[0]=qwq[n+1]=1;
            //计算b中每一项的方案
    		for(int i=1;i<=k;i++)	
    		{
    			int tmp=id[b[i]]; qwq[b[i]]=0;
    			if(!qwq[lst[lst[tmp].l].v]) {qaq[i]++; del(lst[tmp].l);}
    			if(!qwq[lst[lst[tmp].r].v])
    			{
    				qaq[i]++;
    				if(qaq[i]==1) del(lst[tmp].r);
    			}
    		} 
            //统计答案
    		int ans=1;
    		for(int i=1;i<=k;i++) ans=(ans*qaq[i])%mod;
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    json转换成对象
    查看本机电脑的dns
    springboot整合jsp
    mysql DATE_FORMAT()函数用法
    checkbox全选反选
    mysql 中GROUP_CONCAT使用
    checkeds 选中获取tbale表格中某一列td标签中的值
    工具方法整理
    java开发微信公众号支付(JSAPI)
    Could not create connection to database server. Attempted reconnect 3 times. Giving up.错误
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14220556.html
Copyright © 2011-2022 走看看