Smiling & Weeping
----第一次见你的时候,
在我的心里已经炸成了烟花,
需要用一生来打扫灰炉。
题目大意不难,就是把每种情况枚举,但是记录每种String需要想办法,简单的set<string>会MLE不可行,unordered_set<string>也不行,这就需要我吗使用类似于hashcode一般,用pair<int,int>的形式来记录每种不同的情况,题目解析在代码里:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int t , n , m; 4 int main() 5 { 6 scanf("%d",&t); 7 while(t--) 8 { 9 scanf("%d%d",&n,&m); 10 vector<int> lf(n+10) , rg(n+10); 11 string s; 12 cin >> s; 13 lf[0] = -1; //当s[0]=='1'的时候赋值-1,s[0]=='0'的时候赋值0,便于区分 14 for(int i = 0; i < n; i++) 15 { 16 if(i > 0) lf[i] = lf[i-1]; 17 if(s[i] == '0') lf[i] = i; 18 } 19 rg[n-1] = n; //当s[n-1]=='1'时赋值n-1,s[n-1]=='0'的时候赋值n 20 for(int i = n-1; i >= 0; i--) 21 { 22 if(i < n-1) rg[i] = rg[i+1]; 23 if(s[i] == '1') rg[i] = i; 24 } 25 // 如果不区分,这是两种不同的情况,比如:01101001011 , 11101001010就无法区分rg出现错误,lf[0]根本没区别 26 // 如果使用set<string> p必会MLE,ε=(´ο`*)))唉,数据结构好用,但是占用空间太大了 27 set<pair<int , int> > p; 28 while(m--) 29 { 30 int a , b; 31 scanf("%d%d",&a,&b); 32 if(a > b) swap(a,b); //不要问我从哪里得到的教训[○・`Д´・ ○] 33 int ll = rg[a-1] , rr = lf[b-1]; // 计算左端点标记1的历史索引,再求右端点0的历史索引 34 if(ll > rr) 35 { 36 p.insert(make_pair(-1,-1)); 37 } 38 else 39 p.insert(make_pair(ll , rr)); 40 } 41 cout << p.size() << endl; 42 } 43 return 0; 44 }
文章到此结束,我们下次再见,ヾ( ̄▽ ̄)Bye~Bye~
标签:lf,Binary,set,String,int,ll,rg,Copying,赋值 From: https://www.cnblogs.com/smiling-weeping-zhr/p/17592384.html