【离线】【递推】【multiset】 Codeforces Round #401 (Div. 2) C. Alyona and Spreadsheet
对询问按右端点排序,对每一列递推出包含当前行的单调不下降串最多向前延伸多少。
用multiset维护,取个最小值,看是否小于等于该询问的左端点。
#include<cstdio> #include<vector> #include<algorithm> #include<set> using namespace std; multiset<int>S; #define INF 2147483647 struct Data { int l,r,p; }b[100010]; bool cmp(const Data &a,const Data &b) { return a.r<b.r; } int n,m,q,ls[100010]; bool anss[100010]; vector<int>a[100010]; int main() { // freopen("c.in","r",stdin); int x; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) a[i].push_back(0); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { scanf("%d",&x); a[i].push_back(x); } scanf("%d",&q); for(int i=1;i<=m+1;++i) a[0].push_back(INF); for(int i=1;i<=q;++i) { scanf("%d%d",&b[i].l,&b[i].r); b[i].p=i; } sort(b+1,b+1+q,cmp); for(int i=1;i<=q;++i) { for(int j=b[i-1].r+1;j<=b[i].r;++j) for(int k=1;k<=m;++k) if(a[j][k]<a[j-1][k]) { multiset<int>::iterator it=S.find(ls[k]); if(it!=S.end()) S.erase(it); ls[k]=j; S.insert(j); } if((*S.begin())<=b[i].l) anss[b[i].p]=1; } for(int i=1;i<=q;++i) puts(anss[i] ? "Yes" : "No"); return 0; }
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/