Submission #794626

#TimeUsernameProblemLanguageResultExecution timeMemory
794626I_Love_EliskaM_Paint By Numbers (IOI16_paint)C++14
100 / 100
1100 ms343376 KiB
#include "paint.h" #include <bits/stdc++.h> using namespace std; #define forn(i,n) for(int i=0;i<n;++i) #define pb push_back #define all(x) x.begin(), x.end() #define pi pair<int,int> #define f first #define s second const int inf=1e9+9; const int N=2e5+55; const int K=105; int dp[N][K]; int dp2[N][K]; int can[N]; int cant[N]; void yes(int l, int r) { can[l]++; can[r+1]--; } int query(vector<int>&a, int l, int r) { if (l>r) return 0; return a[r+1]-a[l]; } string solve_puzzle(string s, vector<int> c) { s+='_'; int n=s.size(); int k=c.size(); forn(i,n) cant[i]=0; vector<int> X(n+1), _(n+1); forn(i,n) X[i+1]=X[i]+(s[i]=='X'); forn(i,n) _[i+1]=_[i]+(s[i]=='_'); vector<vector<int>> pos(k+1); vector<int> it(k+1); pos[0].pb(0); dp[0][0]=1; for(int i=1; i<=n; ++i) { forn(j,k) { int x=c[j]+1; if (i-x<0) continue; if (!pos[j].size()) continue; if (pos[j][0]>i-x) continue; int last; while (it[j]<pos[j].size() && pos[j][it[j]]<=i-x) ++it[j]; --it[j]; last=pos[j][it[j]]; int y=1, z=1; y&=query(_,i-x,i-2)==0; y&=s[i-1]!='X'; z&=query(X,last,i-x-1)==0; dp[i][j+1]=y&z; if (dp[i][j+1]) pos[j+1].pb(i); } } vector<vector<int>> pos2(k+2); vector<int> it2(k+2); pos2[k+1].pb(n+1); dp2[n+1][k+1]=1; for (int i=n; i>0; --i) { for(int j=k; j>0; --j) { int x=c[j-1]+1; if (i+x>n+1) continue; if (!dp[i+x-1][j]) continue; if (!pos2[j+1].size()) continue; if (pos2[j+1][0]<i+x) continue; int last; for(auto&v:pos2[j+1]) if (v>=i+x) last=v; while (it2[j+1]<pos2[j+1].size() && pos2[j+1][it2[j+1]]>=i+x) ++it2[j+1]; --it2[j+1]; last=pos2[j+1][it2[j+1]]; int y=1, z=1; y&=query(_,i-1,i+x-3)==0; y&=s[i+x-2]!='X'; z&=query(X,i+x-2,last-2)==0; dp2[i][j]=y&z; if (dp2[i][j]) pos2[j].pb(i); } } it.assign(k+1,0); it2.assign(k+2,0); for (int i=1; i<=n; ++i) { forn(j,k+1) { if (pos[j][0]>i) continue; if (pos2[j+1][0]<=i) continue; int l,r; while (it[j]<pos[j].size() && pos[j][it[j]]<=i) ++it[j]; --it[j]; l=pos[j][it[j]]; while (it2[j+1]<pos2[j+1].size() && pos2[j+1][it2[j+1]]>i) ++it2[j+1]; --it2[j+1]; r=pos2[j+1][it2[j+1]]; int z=1; z&=query(X,l,r-2)==0; if (z) cant[i-1]=1; //cout<<"? "<<i<<' '<<j<<' '<<l<<' '<<r<<" "<<z<<'\n'; } } for (int i=0; i<=n+1; ++i) dp[i][0]=dp2[i][k+1]=1; it2.assign(k+2,0); for (int i=1; i<=n; ++i) { for(int j=1; j<=k; ++j) { int x=c[j-1]+1; if (dp[i][j]) { if (!dp2[i-x+1][j]) continue; if (pos2[j+1][0]<=i) continue; int last; while (it2[j+1]<pos2[j+1].size() && pos2[j+1][it2[j+1]]>i) ++it2[j+1]; --it2[j+1]; last=pos2[j+1][it2[j+1]]; if (dp2[last][j+1]) { yes(i-x,i-2); } } } } string ans(n,'?'); int sum=0; forn(i,n) { sum+=can[i]; if (sum) { if (cant[i]) continue; ans[i]='X'; } else { ans[i]='_'; } } forn(i,n) { if (s[i]=='X') { assert(ans[i]!='_'); ans[i]='X'; } } ans.pop_back(); return ans; }

Compilation message (stderr)

paint.cpp: In function 'std::string solve_puzzle(std::string, std::vector<int>)':
paint.cpp:56:25: warning: comparison of integer expressions of different signedness: '__gnu_cxx::__alloc_traits<std::allocator<int>, int>::value_type' {aka 'int'} and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   56 |             while (it[j]<pos[j].size() && pos[j][it[j]]<=i-x) ++it[j];
paint.cpp:87:28: warning: comparison of integer expressions of different signedness: '__gnu_cxx::__alloc_traits<std::allocator<int>, int>::value_type' {aka 'int'} and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   87 |             while (it2[j+1]<pos2[j+1].size() && pos2[j+1][it2[j+1]]>=i+x) ++it2[j+1];
paint.cpp:112:25: warning: comparison of integer expressions of different signedness: '__gnu_cxx::__alloc_traits<std::allocator<int>, int>::value_type' {aka 'int'} and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  112 |             while (it[j]<pos[j].size() && pos[j][it[j]]<=i) ++it[j];
paint.cpp:116:28: warning: comparison of integer expressions of different signedness: '__gnu_cxx::__alloc_traits<std::allocator<int>, int>::value_type' {aka 'int'} and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  116 |             while (it2[j+1]<pos2[j+1].size() && pos2[j+1][it2[j+1]]>i) ++it2[j+1];
paint.cpp:139:32: warning: comparison of integer expressions of different signedness: '__gnu_cxx::__alloc_traits<std::allocator<int>, int>::value_type' {aka 'int'} and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  139 |                 while (it2[j+1]<pos2[j+1].size() && pos2[j+1][it2[j+1]]>i) ++it2[j+1];
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...