Solved: 00:10 zkp
#include
using namespace std;
long long a[200010],b[200010];
int main() {
int n,m;
long long ans=0,sum,t;
cin>>n;
for(int i=0;i<n;i++)
{
sum=0;
cin>>m;
for(int j=0;j<m;j++)scanf("%lli",&t),sum=max(sum,t);
a[i]=sum,b[i]=m;
}
sum=0;
for(int i=0;i<n;i++)sum=max(sum,a[i]);
for(int i=0;i<n;i++)ans+=(sum-a[i])*b[i];
cout<<ans<<endl;
return 0;
}
傻逼签到xD
#include
using namespace std;
#define SZ(x) ((int)(x).size())
vector<string> a;
vector<pair<string, string> > t;
map<string, string> smap;
string const BEGIN = "\\begin{thebibliography}{99}";
string const END = "\\end{thebibliography}";
vector<string> solve(string s) {
vector<string> ret;
for (int i = 0; i + 6 < SZ(s); ++i)
if (s[i] == '\\' && s.substr(i, 6) == "\\cite{") {
int num = 0, canf = 0;
for (int j = i + 6; j < SZ(s); ++j)
if (s[j] == '}') {
canf = 1;
break;
} else
++num;
if (canf) {
ret.push_back(s.substr(i + 6, num));
i = i + 6 + num;
} else
i = SZ(s);
}
return ret;
}
int main() {
string str;
while (str != BEGIN) {
getline(cin, str);
auto vt = solve(str);
for (auto& s : vt)
a.push_back(s);
}
while (getline(cin, str)) {
if (str == END)
break;
int num = 0;
for (int j = 9; j < SZ(str); ++j)
if (str[j] == '}')
break;
else
++num;
string st = str.substr(9, num);
t.push_back(make_pair(st, str));
smap[st] = str;
}
assert(SZ(a) == SZ(t));
bool fans = 1;
for (int i = 0; i < SZ(t); ++i)
if (t[i].first != a[i]) {
fans = 0;
break;
}
if (fans)
puts("Correct");
else {
puts("Incorrect");
cout << BEGIN << '\n';
for (auto& s : a)
cout << smap[s] << '\n';
cout << END << '\n';
}
}
Unsolved
Solved: 00:32 zkp
构造好快啊
#include
using namespace std;
vector<int>a[100010];
int ans[100010];
int main()
{
int n,m,x,y;
cin>>n>>m;
for(int i=0;i<m;i++)
{
cin>>x>>y;
a[x].push_back(y);
a[y].push_back(x);
}
if(n==1)
{
cout<<"NO"<<endl;
return 0;
}
x=-1,y=-1;
for(int i=1;i<=n;i++)
{
a[i].push_back(i);
sort(a[i].begin(),a[i].end());
if(a[i][0]!=1)x=i,y=1;
for(int j=1;j<a[i].size();j++)if(a[i][j]!=a[i][j-1]+1)x=i,y=a[i][j-1]+1;
}
if(x==-1)
{
cout<<"NO"<<endl;
return 0;
}
int now=3;
cout<<"YES\n";
for(int i=1;i<=n;i++)if(i!=x&&i!=y)ans[i]=now++;
ans[x]=1,ans[y]=2;
for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
cout<<endl;
ans[y]=1;
for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
cout<<endl;
return 0;
}
Solved: 02:44 zkp
一个点到另一个点的步数不会超过10步的样子?
#include
using namespace std;
int mp[10][10];
int dx[]={1,1,-1,-1,2,2,-2,-2};
int dy[]={2,-2,-2,2,1,-1,1,-1};
int px[10][10],py[10][10];
vector<int>ans[4];
void prt(int x,int y,int rx,int ry)
{
if(x==rx&&y==ry)return;
if(mp[px[rx][ry]][py[rx][ry]])prt(x,y,px[rx][ry],py[rx][ry]);
ans[0].push_back(rx),ans[1].push_back(ry);
ans[2].push_back(px[rx][ry]),ans[3].push_back(py[rx][ry]);
if(!mp[px[rx][ry]][py[rx][ry]])prt(x,y,px[rx][ry],py[rx][ry]);
}
void BFS(int x,int y)
{
if(mp[x][y]==1)
{
mp[x][y]=-1;
return;
}
for(int i=0;i<10;i++)for(int j=0;j<10;j++)px[i][j]=py[i][j]=0;
px[x][y]=-1;
queue<pair<int,int> >q;
q.push(make_pair(x,y));
int nx,ny,gx=10,gy=-1,ex,ey;
while(!q.empty())
{
nx=q.front().first;
ny=q.front().second;
q.pop();
for(int i=0;i<8;i++)
{
ex=nx+dx[i];ey=ny+dy[i];
if(ex>8||ex<1||ey>8||ey<1)continue;
if(px[ex][ey])continue;
px[ex][ey]=nx;
py[ex][ey]=ny;
if(mp[ex][ey]==1&&(ex<gx||(ex==gx&&ey<gy)))gx=ex,gy=ey;
q.push(make_pair(ex,ey));
}
}
prt(x,y,gx,gy);
mp[gx][gy]=0,mp[x][y]=-1;
}
int main()
{
int n;
cin>>n;
string s;
for(int i=0;i<n;i++)cin>>s,mp[s[0]-'a'+1][s[1]-'0']=1;
for(int i=0;i<n;i++)
{
BFS(i%8+1,i/8+1);
}
cout<<ans[1].size()<<endl;
for(int i=0;i<ans[1].size();i++)
{
cout<<char(ans[0][i]+'a'-1)<<ans[1][i]<<"-";
cout<<char(ans[2][i]+'a'-1)<<ans[3][i]<<"\n";
}
return 0;
}
Unsolved
Unsolved
Unsolved
Solved: 01:30 zkp
-8太dirt了吧,以后要让zkp控制好罚时才行
单调栈
#include
using namespace std;
unsigned int b[10000010];
long long a[10000010];
long long st[10000010];
int main()
{
int t;
cin>>t;
while(t--)
{
long long n,l,r,x,y,z,now=9223372036854775807ll,ans=9223372036854775807ll,sz=0;
cin>>n>>l>>r>>x>>y>>z>>b[1]>>b[2];
for(int i=3;i<=n;i++)b[i]=(b[i-2]*x+b[i-1]*y+z);
for(int i=1;i<=n;i++)a[i]=b[i]%(r-l+1)+l;
for(int i=1;i<=n;i++)
{
if(a[i]>=0)
{
if(a[i]>now)ans=min(ans,a[i]*now);
now=min(a[i],now);
continue;
}
now=min(now,a[i]);
while(sz!=0&&st[sz]<a[i])ans=min(ans,st[sz]*a[i]),sz--;
st[++sz]=a[i];
}
if(ans==9223372036854775807ll)cout<<"IMPOSSIBLE\n";
else cout<<ans<<endl;
}
return 0;
}
Solved: 04:27 BPM136
询问两个串的前缀连接成的本质不同的字符串有多少个
如果两个连接相同,那么第一个串的某个位置结束的后缀和第二个串某个位置i的长度为i-nxt[i]长度的前缀完全相同。
那么对于第二个串kmp
第一个串SAM,来统计那个前缀有多少个
然后对于每个i-nxt[i]的前缀在SAM上跑就可以统计答案了
#include
using namespace std;
#define SZ(x) ((int)(x).size())
using ll = long long;
const int N = 200005;
int ch[N][26], sam_sz[N], par[N], mx[N];
int v[N];
int sam_cnt, sam_last;
void SAM_init() {
sam_cnt = sam_last = 1;
memset(ch, 0, sizeof(ch));
memset(par, 0, sizeof(par));
memset(mx, 0, sizeof(mx));
memset(sam_sz, 0, sizeof(sam_sz));
}
int SAM_extend(int x) {
if(ch[sam_last][x]) {
int p = sam_last, q = ch[p][x];
if(mx[q] == mx[p] + 1) return sam_last = q, q;
int nq = ++sam_cnt;
mx[nq] = mx[p] + 1;
memcpy(ch[nq], ch[q], sizeof(ch[q]));
par[nq] = par[q];
par[q] = nq;
for(; ch[p][x] == q; p = par[p]) ch[p][x] = nq;
return sam_last = nq, nq;
}
int p, q, np, nq;
p = sam_last;
sam_last = np = ++sam_cnt;
mx[np] = mx[p] + 1;
sam_sz[np] = 1;
for(; p && !ch[p][x]; p = par[p]) ch[p][x] = np;
if(!p) par[np] = 1;
else {
q = ch[p][x];
if(mx[q] == mx[p] + 1) par[np] = q;
else {
nq = ++sam_cnt;
mx[nq] = mx[p] + 1;
memcpy(ch[nq], ch[q], sizeof(ch[q]));
par[nq] = par[q];
par[q] = par[np] = nq;
for(; ch[p][x] == q; p = par[p]) ch[p][x] = nq;
}
}
return sam_last;
}
int samt[N];
void SAM_topoSort() {
static int b[N];
memset(b, 0, sizeof(b));
memset(samt, 0, sizeof(samt));
for(int i = 1; i <= sam_cnt; i++) b[mx[i]]++;
for(int i = 1; i <= sam_cnt; i++) b[i] += b[i - 1];
for(int i = sam_cnt; i >= 1; i--) samt[b[mx[i]]--] = i;
for(int i = sam_cnt; i >= 1; i--) sam_sz[par[samt[i]]] += sam_sz[samt[i]];
for(int i = sam_cnt; i >= 1; --i)
v[par[samt[i]]] += v[samt[i]];
}
int nxt[N];
int num[N];
void KMP(string& s) {
nxt[0] = 0;
for (int i = 1, j = 0, m = (int)s.size(); i < m; ++i) {
while (j && s[i] != s[j])
j = nxt[j - 1];
if (s[i] == s[j])
++j;
nxt[i] = j;
}
}
int main() {
string s1, s2;
cin >> s1 >> s2;
SAM_init();
for (int i = 1; i < SZ(s1); ++i)
SAM_extend(s1[i] - 'a');
int p = 1;
for (int i = 1; i < SZ(s1); ++i) {
p = ch[p][s1[i] - 'a'];
v[p] = 1;
}
SAM_topoSort();
v[0] = 0;
KMP(s2);
for (int i = 0; i < SZ(s2); ++i)
if (nxt[i] != 0)
num[i - nxt[i]]++;
ll ans = (ll)SZ(s1) * SZ(s2);
p = 1;
for (int i = 0; i < SZ(s2); ++i) {
p = ch[p][s2[i] - 'a'];
ans -= (ll)num[i] * v[p];
}
cout << ans << '\n';
}
Solved: 02:12 BPM136
两个串互为subsequence iff 两个串的t字符集相同 和 s串的到最后的某个不在t串中出现的字符的前缀完全相同
然后map套map就好了
#include
using namespace std;
#define SZ(x) ((int)(x).size())
map<unsigned, map<string, vector<int> > > g;
int main() {
int n;
cin >> n;
string s, t;
for (int i = 0; i < n; ++i) {
cin >> s >> t;
unsigned st = 0;
for (auto& c : t)
st |= 1u << (c - 'a');
int pos = 0;
for (int j = SZ(s) - 1; j >= 0; --j)
if (((1u << (s[j] - 'a')) & st) == 0) {
pos = j + 1;
break;
}
auto& mt = g[st];
mt[s.substr(0, pos)].push_back(i + 1);
}
int ans = 0;
for (auto& p : g) {
auto& mt = p.second;
ans += SZ(mt);
}
cout << ans << '\n';
for (auto& p : g) {
auto& mt = p.second;
for (auto& v : mt) {
cout << SZ(v.second);
for (auto& id : v.second)
cout << ' ' << id;
cout << '\n';
}
}
}
Solved: 00:33 BPM136
二分后判定即可
#include
using namespace std;
using ll = long long;
ll n, m, a, b, k, x, y;
bool check(ll t) {
return min(t, a) * x + min(t, b) * y >= t * k;
}
int main() {
cin >> n >> m >> a >> b >> k;
x = y = m / 2;
if (m % 2)
++x;
ll l = 1, r = n;
ll ans = 0;
while (l <= r) {
ll mid = (l + r) >> 1;
if (check(mid)) {
ans = mid;
l = mid + 1;
} else
r = mid - 1;
}
cout << ans << '\n';
return 0;
}
Solved: 00:15 BPM136
温暖的签到
然而我怎么不会线性呢,一眼二分是什么玩意
#include
using namespace std;
int a[100005];
int v[100005];
bool check(int mid, int n) {
for (int i = 1; i <= n - mid + 1; ++i) {
int l = i, r = i + mid - 1;
if (v[r - 1] - v[l] == mid - 2 && a[l] != a[l + 1] && a[r] != a[r - 1])
return 1;
}
return 0;
}
int main() {
int n, m;
ios::sync_with_stdio(0);
cin >> n >> m;
for (int i = 1; i <= n; ++i)
cin >> a[i];
a[0] = a[n + 1] = -1;
for (int i = 1; i <= n; ++i)
if (a[i] != a[i - 1] && a[i] != a[i + 1])
v[i] = 1;
for (int i = 1; i <= n; ++i)
v[i] += v[i - 1];
int l = 1, r = n;
int ans = 1;
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid, n)) {
l = mid + 1;
ans = mid;
} else
r = mid - 1;
}
cout << ans << '\n';
return 0;
}