首页 > 其他分享 >CF1826E nowcoder55993G - bitset -

CF1826E nowcoder55993G - bitset -

时间:2023-05-06 11:11:45浏览次数:48  
标签:01 nowcoder55993G int long maxn bitset CF1826E define

CF1826E
这个题比赛的时候基本做出来了,就是不会用 bitset 导致最后寄了。这已经是第三次很有希望做出 E 最后没有做出来了 /ll
好几个月了一直卡在四题,吐了

首先如果对于一个模特,她在 \(i\) 城市的所有分数都分别小于 \(j\) 城市的,那么就 \(i\rightarrow j\) 连一条边,显然这是若干个 DAG,跑 dp 即可

如何判断“分别小于”这个条件?直接判断是 \(O(n^2m)\) 的,显然不行
考虑先固定一个城市,然后按照这个城市的评分对模特排序。考虑对于一个模特,有哪些模特比她小,显然可以用一个 01 串表示。由于小于具有传递性,因此这个 01 串也是可以继承的,每次找到相同的一串人的评分,就更新这一串人的 01 串即可。
可以用 bitset<5002> bit[5002] 维护,其中 bit[i][j] 表示 \(i\rightarrow j\) 是否有边
回到本题,如果 \(i\rightarrow j\) 有边,即 \(i\) 模特比 \(j\) 模特的所有城市的评分都要低,我们可以对每一个城市中 模特 \(i\) 的 01 串取 and(\(bit[i][j]\) 这一位为 1 代表 \(i\) 在某一个城市比 \(j\) 小,取了 & 也就是要求所有的城市都比 \(j\) 小)
复杂度瓶颈在于每次对两个城市 01 串 & 的时候,bitset 优化复杂度 /32
时间复杂度 \(O(n^2m/32)\)

55993G
考虑对于 \(b_i\) 维护有哪些 \(a_j\) 满足 \(a_j\geq b_i\)
例如样例中 \(b_1=2\) 对应的 01 串就是 \(011111\)
问题转化为了有多少个“阶梯型”的 1 ,因为这种才能满足 \(S_i\geq B_i\) 条件
如样例:
011111
010111
010111

发现 \(b_i\) 大的可以由 \(b_i\) 小的继承过来,直接从小到大计算即可,计算阶梯型可以用右移取 &

思考:能用 bitset 是因为这两题都涉及了大小关系,也就是 01 关系,使用 bitset 可以减小 取& 的复杂度

1826E

// by SkyRainWind
#include <bits/stdc++.h>
#define mpr make_pair
#define debug() cerr<<"Yoshino\n"
#define pii pair<int,int>
#define pb push_back

using namespace std;

typedef long long ll;
typedef long long LL;

const int inf = 1e9, INF = 0x3f3f3f3f, maxn = 5005;

int m,n;
int p[maxn];
pii a[maxn];
bitset<5005>g[5005];
vector<int>gr[5005];

signed main(){
	scanf("%d%d",&m,&n);
	for(int i=1;i<=n;i++)scanf("%d",&p[i]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)g[i][j] = 1;
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++)scanf("%d",&a[j].first), a[j].second = j;
		sort(a+1,a+n+1);
		bitset<5005>can;
		for(int i=1;i<=n;){
			int j=i;
			while(j<n && a[j+1].first == a[i].first)++ j;
			for(int k=i;k<=j;k++){
				g[a[k].second] &= can;
			}
			for(int k=i;k<=j;k++)
				can[a[k].second] = 1;
			
			i = j+1;
		}
	}
	
	vector<int>de(n+1, 0);
	vector<ll> dp(n+1, 0);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(g[i][j])gr[i].pb(j), ++ de[j];
		}
	}
	
	queue<int>Q;
	for(int i=1;i<=n;i++)if(!de[i])Q.push(i);
	ll ans = 0;
	for(int i=1;i<=n;i++)dp[i] = p[i], ans = max(ans, dp[i]);
	
	while(!Q.empty()){
		int u = Q.front();Q.pop();
		for(int v : gr[u]){
			dp[v] = max(dp[v], dp[u] + p[v]);
			ans = max(ans, dp[v]);
			if(!--de[v])Q.push(v);
		}
	}
	printf("%lld\n",ans);

	return 0;
}

55993G

// by SkyRainWind
#include <bits/stdc++.h>
#define mpr make_pair
#define debug() cerr<<"Yoshino\n"
#define pii pair<int,int>
#define pb push_back

using namespace std;

typedef long long ll;
typedef long long LL;

const int inf = 1e9, INF = 0x3f3f3f3f, maxn = 2e5+5;

int n,m;
pii a[maxn], b[maxn];

signed main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i].first),a[i].second = i;
	for(int i=1;i<=m;i++)scanf("%d",&b[i].first),b[i].second = i;
	
	sort(a+1,a+n+1,[&](pii a,pii b){return a.first>b.first;});
	sort(b+1,b+m+1,[&](pii a,pii b){return a.first>b.first;});
	
	bitset<150002>now,ans;
	for(int i=1;i<=n;i++)ans[i] = 1;
	for(int i=1,j=0;i<=m;i++){
		int lst = j;
		while(lst < n && a[lst+1].first >= b[i].first){
			now[a[lst+1].second] = 1;
//			printf("! %d\n",a[lst+1].second);
			++ lst;
		}
//		debug();
		ans &= now >> (b[i].second-1);
		j = lst;
	}
	printf("%d\n",ans.count());

	return 0;
}

标签:01,nowcoder55993G,int,long,maxn,bitset,CF1826E,define
From: https://www.cnblogs.com/SkyRainWind/p/17376655.html

相关文章

  • LOJ #6564 - 最长公共子序列(bitset 求 LCS)
    怎么全天下就我没见过?被薄纱了/ll还是考虑从朴素的DP入手优化。不难发现对于固定的\(i\),相邻的\(dp_{i,j}\)的差要么是\(0\)要么是\(1\),也就是说从压位的考虑角度可能很有前途。因此我们转而维护\(dp_{i,j}\)的差分数组\(v_{i,j}=dp_{i,j}-dp_{i,j-1}\)。考虑新添加一......
  • AcWing 可达性统计(bitset
    可达性统计建图图的存储拓扑排序:DAG(有向无环图),往拓扑排序思考。拓扑排序的目标是将所有节点排序,使得排在前面的节点不能依赖于排在后面的节点。此类问题需要使用bitset优化。bitset在bitset头文件中,它类似数组,并且每一个元素只能是0或1,每个元素只用1bit空间,可看作几个in......
  • bitset数组
    bitset的用法及例题(对DP过程的优化)  bitset这容器有点离谱,卡常优化空间神器。什么是bitset?bitset是c++STL里面的一个容器,可以理解为存放01串的,很奇怪,bool[]不也一样能实现这个功能?不是这样的,bool每个元素占一个字节,也就是8bit,而bitset中每个串中的01值每个只占一个bit!!!......
  • DUTOJ 1282: Zeratul与a+b=c bitset 小内存数组
    问题1282--Zeratul与a+b=c1282:Zeratul与a+b=c时间限制:1Sec  内存限制:32MB提交:148  解决:25[提交][状态][讨论版][命题人:Zeratul]题目描......
  • 递归 Problem N:Bitset(HDU 2051)
    ProblemNTimeLimit:1000/1000ms(Java/Other)   MemoryLimit:32768/32768K(Java/Other)TotalSubmission(s):3   AcceptedSubmission(s):1ProblemDescr......
  • Codeforces Round 368 (Div. 2) D. Persistent Bookcase 主席树维护bitset
    在学主席树时找到了这道题本来yyyy了一个二维的主席树这种东西,然后发现很多信息好像维护不了观察到n和m都很小,考虑把一整行看成一个节点,开一个bitset然后区间取反、单点......
  • P1441 砝码称重 状压+bitset的组合
    这道题最妙的是移入bitset,来统计能组成那些数令bitset<2010>S;一开始初始化S[0]=1对于w[i],S<<w[i]表示原本能组成的数加上w[i]后组成的新数但原本的数我们依旧是要的......
  • Java位集合之BitMap,BitSet解析
    目录1Java位集合1.1Bit-Map1.1.1简介1.1.2添加1.1.3清除1.1.4查找1.2Bitmap应用1.2.1快速排序1.2.2快速去重1.2.3快速查找1.3BitSet1.4BloomFilters1.4.1简......
  • C++ 中的 bitset
    C++中的\(\textsf{bitset}\)是能够存储\(01\)的容器,这一点看似与布尔(bool)数组很像。而一个布尔类型将会占用\(1\)字节的空间,相对于\(\textsf{bitset}\)来讲\(1\)......
  • bitset小专题(待续)
    bitset:一个01位如果用bool存的话需要1byte,而用bitset只需要1bit(=1/8byte)每次两个集合取并的时候可以除以一个大常数(32/64),从而优化复杂度LOJ515设\(dp[i]\)表示考......