commit 43ced8bd2a0b7e73327ec4538832fc70e22ad6b4 Author: ZhuangYumin Date: Sat Dec 23 22:23:48 2023 +0800 Init diff --git a/ACMOJ-1018.cpp b/ACMOJ-1018.cpp new file mode 100644 index 0000000..1ddf39e --- /dev/null +++ b/ACMOJ-1018.cpp @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include +#include +// #include +using namespace std; +typedef long long LL; +typedef pair SufType; +const int maxn=1005; +int N,K,a[maxn]; +bool used[maxn]; +vector position,number; +LL OuterPair[20][20],stk[20],Answer,TotalNotFixed,InnerPair[1<<14][20]; +int hsh[(1<<14)+1]; +int PreLength,SufLength; +struct Hash_SufType2LongLong +{ + const static int PoolSize=17297280*3; + const static LL a=233331,b=19260817; + LL Pool[PoolSize]; + int head[PoolSize],nxt[PoolSize],stv[PoolSize],CntV[PoolSize],PoolCnt=0; + inline LL& operator[](const SufType &key) + { + const LL HashValue=(key.first*a+key.second+b)%PoolSize; + // return Pool[HashValue]; + int p=head[HashValue]; + while(p) + { + if(stv[p]==key.first&&CntV[p]==key.second) return Pool[p]; + p=nxt[p]; + } + PoolCnt++; + nxt[PoolCnt]=head[HashValue]; + stv[PoolCnt]=key.first; + CntV[PoolCnt]=key.second; + head[HashValue]=PoolCnt; + return Pool[PoolCnt]; + } +}SufData; +void dfs(int dep,LL CurrentPair,int st) +{ + if(dep==PreLength) + { + Answer+=SufData[SufType(((1<CurrentPair+(TotalNotFixed-dep)*(TotalNotFixed-dep-1)/2+(TotalNotFixed-dep)*(N-TotalNotFixed+dep))) + { + stk[dep]=number[i]; + dfs(dep+1,CurrentPair+InnerPair[st][i]+OuterPair[dep][i],st|(1<a[j]) + AlreadyHave++; + for(int i=1;i<=N;i++) + if(!used[i]) + number.push_back(i); + TotalNotFixed=position.size(); + for(int i=0;inum)||(a[k]!=0&&k>pos&&a[k]number[p]) + InnerPair[st][p]++; + if(K>AlreadyHave+TotalNotFixed*(TotalNotFixed-1)/2+TotalNotFixed*(N-TotalNotFixed)) + { + puts("0"); + return 0; + } + for(int i=0;i +#include "ACMOJ-1040.hpp" + +int a[9] = {1, 5, 6, 2, 7, 3, 9, 4, 8}; + +bool cmp(const int &x, const int &y){return x > y;} + +int main() +{ + nth_element(a, a + 8, a + 9, cmp);//find the 8th(0-base) greatest value in a with cmp as comparator + std::cout << *(a + 5) << std::endl;// 4 + sort(a, a + 9, [](const int &x, const int &y){return x < y;});//comp is a lambda expression, which returns true if and only if x < y + for (int i = 0;i < 9;++ i) std::cout << a[i] << " ";// 1 2 3 4 5 6 7 8 9 + std::cout << std::endl; + return 0; +} \ No newline at end of file diff --git a/ACMOJ-1040.hpp b/ACMOJ-1040.hpp new file mode 100644 index 0000000..58e0578 --- /dev/null +++ b/ACMOJ-1040.hpp @@ -0,0 +1,37 @@ +#pragma once +#ifndef __PROTECTOR_ACMOJ_1040__ +#define __PROTECTOR_ACMOJ_1040__ +#include +#include +typedef bool (*Comparator)(const int &, const int &); +std::mt19937 rnd(std::random_device{}()); +void nth_element(int *first, int *nth, int *last, + Comparator comp) { + if (nth == last) return; + while (last - first > 1) { + int *p = first, *q = last - 1, *i = first, *j = last - 1; + int pivot = *(first + rnd() % (last - first)); + while (i < j) { + while (comp(*i, pivot)) ++i; + while (comp(pivot, *j)) --j; + if (i <= j) { + std::swap(*i, *j); + ++i; + --j; + } + } + if (nth <= j) + last = j + 1; + else + first = i; + } +} +void sort(int *first, int *last, + Comparator comp) { + if (last - first <= 1) return; + int *mid = first + (last - first) / 2; + nth_element(first, mid, last, comp); + sort(first, mid, comp); + sort(mid, last, comp); +} +#endif \ No newline at end of file diff --git a/ACMOJ-1048.cpp b/ACMOJ-1048.cpp new file mode 100644 index 0000000..c3795ef --- /dev/null +++ b/ACMOJ-1048.cpp @@ -0,0 +1,13 @@ +#include "ACMOJ-1048.hpp" +#include +void hello() { std::cout << "Hello world!" << std::endl; } + +int main() { + int *p = new int[2]; + Defer defer([&]() { delete[] p; }); + defer([&]() { std::cout << p[0] << " " << p[1] << std::endl; }); + defer([&]() { p[0] = 0, p[1] = 1; }); + defer(hello); + p[0] = 2, p[1] = 3; + return 0; +} \ No newline at end of file diff --git a/ACMOJ-1048.hpp b/ACMOJ-1048.hpp new file mode 100644 index 0000000..961c74e --- /dev/null +++ b/ACMOJ-1048.hpp @@ -0,0 +1,13 @@ +#include +#include +class Defer { + std::stack> stk; + + public: + ~Defer() { + while (!stk.empty()) stk.top()(), stk.pop(); + } + Defer() = default; + Defer(std::function f) { stk.push(f); } + void operator()(std::function f) { stk.push(f); } +}; \ No newline at end of file diff --git a/ACMOJ-1444.cpp b/ACMOJ-1444.cpp new file mode 100644 index 0000000..0dab646 --- /dev/null +++ b/ACMOJ-1444.cpp @@ -0,0 +1,48 @@ +#include "ACMOJ-1444.hpp" +#include +using namespace std; + +int main(){ + #ifdef local + freopen("pro.in","r",stdin); + #endif + int T; + cin >> T ; + while (T--) { + int type; + cin >> type; + + int test_0_st, test_0_ed, test_0_val; + cin >> test_0_st >> test_0_ed >> test_0_val; + Evil test_0_0(test_0_st, test_0_ed, test_0_val); + + if (type == 0){ + test_0_0.Print(); + Evil test_0_1; + test_0_1.Print(); + } + if(type == 1){ + Evil test_1_1; + test_1_1 = test_0_0; + test_1_1.Print(); + } + if(type == 2){ + for(int i = test_0_st;i <= test_0_ed;++i) test_0_0[i] = i; + test_0_0[test_0_st-1] = test_0_st-1; + cout << test_0_0[test_0_st-1] << " " << test_0_0[test_0_ed+1] <<" "; + test_0_0.Print(); + } + if(type == 3){ + test_0_0++; + test_0_0++; + test_0_0.Print(); + + ++test_0_0; ++test_0_0; + test_0_0.Print(); + } + if(type == 4){ + cout << test_0_0; + } + } + return 0; +} \ No newline at end of file diff --git a/ACMOJ-1444.hpp b/ACMOJ-1444.hpp new file mode 100644 index 0000000..83a1d8c --- /dev/null +++ b/ACMOJ-1444.hpp @@ -0,0 +1,72 @@ +#ifndef EVIL_HPP +#define EVIL_HPP + +#include +#include +using namespace std; + +class Evil { + private: + int st, ed, val; + int *data = nullptr; + + public: + // 构造函数 + Evil(int __st = 0, int __ed = 0, int __val = 0) { + st = __st; + ed = __ed; + val = __val; + data = new int[ed - st + 1](); + } + Evil(const Evil &src) { + st = src.st; + ed = src.ed; + val = src.val; + data = new int[ed - st + 1](); + std::memmove(data, src.data, sizeof(int) * (ed - st + 1)); + } + // 下标运算符重载 + int &operator[](int idx) { + if (idx < st || idx > ed) return *data; + return *(data + idx - st); + } + // 赋值运算符重载 + Evil &operator=(const Evil &src) { + delete[] data; + st = src.st; + ed = src.ed; + val = src.val; + data = new int[ed - st + 1](); + std::memmove(data, src.data, sizeof(int) * (ed - st + 1)); + return *this; + } + // 前缀++重载 + Evil &operator++() { + val++; + return *this; + } + // 后缀++重载 + Evil operator++(int) { + Evil ret = *this; + val++; + return ret; + } + // 输出重载 + friend std::ostream &operator<<(std::ostream &stream, const Evil &dat); + // 析构函数 + ~Evil() { delete[] data; } + + void Print() { + cout << val << " "; + for (int i = 0; i < ed - st + 1; ++i) cout << data[i] << " "; + cout << endl; + } +}; + +std::ostream &operator<<(std::ostream &stream, const Evil &dat) { + stream << dat.val; + for (int i = 0; i <= dat.ed - dat.st; i++) stream << ' ' << *(dat.data + i); + stream << std::endl; + return stream; +} +#endif // EVIL_HPP \ No newline at end of file diff --git a/ACMOJ-1447.cpp b/ACMOJ-1447.cpp new file mode 100644 index 0000000..6b7ee8b --- /dev/null +++ b/ACMOJ-1447.cpp @@ -0,0 +1,12 @@ +#include +#include "ACMOJ-1447.hpp" +void print(int argc,char** argv){ + for(int i=0;i +#include +#include +#include +#include +// WARNING: NO more headers allowed! + +using std::function; +using std::map; +using std::pair; +using std::string; +using std::vector; +namespace final { +class arguments { + private: + // WARNING: You cannot add more member variables. + int _argc; + char **_argv; + + public: + arguments() : _argc(0), _argv(nullptr) {} + explicit arguments(const string &cmd) { + // todo implement constructor + int first_pos = 0; + int length = cmd.length(); + _argc = 0; + while (first_pos < length && cmd[first_pos] == ' ') first_pos++; + if (first_pos == length) { + _argv = new char *[1]; + return; + } + std::vector argv_tmp; + for (int i = first_pos + 1; i < length; i++) { + if (cmd[i] != ' ') continue; + _argc++; + char *arg_tmp = new char[i - first_pos + 2]; + std::memmove(arg_tmp, cmd.c_str() + first_pos, i - first_pos); + arg_tmp[i - first_pos] = '\0'; + argv_tmp.push_back(arg_tmp); + first_pos = i + 1; + while (first_pos < length && cmd[first_pos] == ' ') first_pos++; + if (first_pos == length) break; + } + if (first_pos < length) { + _argc++; + char *arg_tmp = new char[length - first_pos + 2]; + std::memmove(arg_tmp, cmd.c_str() + first_pos, length - first_pos); + arg_tmp[length - first_pos] = '\0'; + argv_tmp.push_back(arg_tmp); + } + _argv = new char *[_argc]; + for (int i = 0; i < _argc; i++) _argv[i] = argv_tmp[i]; + // std::cerr << "argc: " << _argc << std::endl; + } + ~arguments() { + // todo implement destructor + for (int i = 0; i < _argc; i++) delete[] _argv[i]; + delete[] _argv; + } + // WARNING: You cannot modify the following functions + int argc() const { return _argc; } + char **argv() const { return _argv; } +}; + +// You don't need to modify shell. +class shell { + private: + map running_list; + + public: + shell() = default; + + void run(int pid, const string &cmd, + const function &invoked) { + running_list.emplace(pid, cmd); + invoked(running_list[pid].argc(), running_list[pid].argv()); + } + + int subprocessExit(int pid, int return_value) { + running_list.erase(pid); + return return_value; + } + vector getRunningList() const { + vector rt; + for (auto &pair : running_list) rt.push_back(pair.first); + return rt; + } +}; +} // namespace final \ No newline at end of file diff --git a/ACMOJ-1663.cpp b/ACMOJ-1663.cpp new file mode 100644 index 0000000..d438c5e --- /dev/null +++ b/ACMOJ-1663.cpp @@ -0,0 +1,14 @@ +#include +#include +#include +using namespace std; +int main() +{ +#ifdef local + freopen("pro.in","r",stdin); +#endif + int n,a,res=0; scanf("%d",&n); + for(int i=0;i +#include +#include +#include +using namespace std; +const int maxn=2e4+5; +int fa[maxn],cnt[maxn]; +int a[maxn],acnt; +bool vis[maxn*2]; +int ff(int u) +{ + int a=u,b; + while(u!=fa[u]) u=fa[u]; + while(a!=u) + { + b=fa[a]; + fa[a]=u; + a=b; + } + return u; +} +int main() +{ +#ifdef local + freopen("pro.in","r",stdin); +#endif + int n,m,k; scanf("%d%d%d",&n,&m,&k); + for(int i=1;i<=n;i++) fa[i]=i; + for(int i=0;i=a[i];j--) + vis[j]|=vis[j-a[i]]; + for(int i=0;;i++) + { + if(m-i<0&&m+i>n) + break; + if(m-i>=0&&vis[m-i]) + { + printf("%d\n",m-i); + return 0; + } + if(m+i<=n&&vis[m+i]) + { + printf("%d\n",m+i); + return 0; + } + } + return 0; +} \ No newline at end of file diff --git a/ACMOJ-1669.cpp b/ACMOJ-1669.cpp new file mode 100644 index 0000000..78e995d --- /dev/null +++ b/ACMOJ-1669.cpp @@ -0,0 +1,61 @@ +#include +#include +#include +using namespace std; +const int inf=0x3f3f3f3f; +const int maxmn=505; +int n,m,d[maxmn],position[maxmn]; +int dp[maxmn][maxmn],pre[maxmn][maxmn],suf[maxmn][maxmn]; +int main() +{ +#ifdef local + freopen("pro.in","r",stdin); +#endif + scanf("%d%d",&n,&m); + for(int i=1;i<=n-1;i++) + scanf("%d",&d[i]); + for(int i=2;i<=n;i++) + position[i]=position[i-1]+d[i-1]; + memset(dp,0x3f,sizeof(dp)); + for(int i=1;i<=n;i++) + { + dp[i][1]=0; + for(int j=i-1;j>=1;j--) + dp[i][1]+=position[i]-position[j]; + for(int j=i+1;j<=n;j++) + dp[i][1]+=position[j]-position[i]; + } + for(int i=1;i<=n;i++) + { + for(int j=i+1;j<=n;j++) + { + pre[i][j]=pre[i][j-1]+position[j]-position[i]; + } + } + for(int i=n;i>=1;i--) + { + for(int j=i-1;j>=1;j--) + { + suf[i][j]=suf[i][j+1]+position[i]-position[j]; + } + } + for(int i=2;i<=n;i++) + for(int j=2;j<=m;j++) + { + int p=i; + for(int k=i-1;k>=1;k--) + { + while(p-1>=1&&position[i]-position[p-1] +#include +#include +#include +#include +#include +#include +#include +#define lowbit(x) ((x)&(-(x))) +using namespace std; +const int maxn=5e5+10; +int a[maxn],N,Q,mp[maxn],QL[maxn],QR[maxn],qid[maxn],res[maxn]; +int BST[maxn]; +int L1[maxn],L2[maxn],L3[maxn]; +bool cmp(int q1,int q2) +{ + return (QR[q1]!=QR[q2])?QR[q1] st; + for(int i=1;i<=N;i++) + { + scanf("%d",&a[i]); + st.insert(a[i]); + } + map hsh; + int hcnt=0; + for(auto it=st.begin();it!=st.end();it++) hsh[*it]=++hcnt; + for(int i=1;i<=N;i++) a[i]=hsh[a[i]]; + for(int i=1;i<=Q;i++) + { + scanf("%d%d",&QL[i],&QR[i]); + qid[i]=i; + } + sort(qid+1,qid+1+Q,cmp); + int qp=1; + for(int i=1;i<=N;i++) + { + Add(L3[a[i]],+1); + L3[a[i]]=L2[a[i]]; + Add(L3[a[i]],-1); + Add(L2[a[i]],-1); + L2[a[i]]=L1[a[i]]; + Add(L2[a[i]],+1); + L1[a[i]]=i; + while(QR[qid[qp]]==i) + { + res[qid[qp]]=query(i)-query(QL[qid[qp]]-1); + qp++; + } + } + for(int i=1;i<=Q;i++) printf("%d\n",res[i]); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-1686.cpp b/ACMOJ-1686.cpp new file mode 100644 index 0000000..ad3c09c --- /dev/null +++ b/ACMOJ-1686.cpp @@ -0,0 +1,238 @@ +#include +#include +#include +#include +#include +#define unlikely(x) __builtin_expect(!!(x), 0) +struct char_reader +{ + FILE* f; char *buf,*p1,*p2; int size; + char_reader(FILE* fin,int bufsize=1<<16) { f=fin; size=bufsize; p1=p2=0; buf=new char[size]; } + ~char_reader() { delete []buf; } + inline int operator()() { return p1==p2&&(p2=(p1=buf)+fread(buf,1,size,f),p1==p2)?EOF:*p1++; } +}; +struct char_writer +{ + FILE* f; char *buf,*p,*end; int size; + char_writer(FILE* fout,int bufsize=1<<16) { f=fout; size=bufsize; buf=new char[size]; p=buf; end=buf+bufsize; } + ~char_writer() { fwrite(buf,p-buf,1,f); delete []buf; } + inline char operator()(char ch) + { + if(unlikely(end==p)) { fwrite(buf,end-buf,1,f); p=buf; } + return *p++=ch; + } +}; +char_reader gch(stdin); +char_writer wch(stdout); +template inline int read(T& t) +{ + bool f=false; int ch; while(ch=gch(),!((ch>='0'&&ch<='9')||ch=='-')) { if(ch==EOF) return 0; } + t=0; + if(ch=='-') f=true,ch=gch(); t=ch^48; while(ch=gch(),ch>='0'&&ch<='9') t=(t<<3)+(t<<1)+(ch^48); + if(f) t=-t; + return 1; +} +inline int read(char &c) +{ + c=0; int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } c=ch; + return 1; +} +inline int read(char *s) +{ + int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } + *s++=ch; while(ch=gch(),!(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')&&ch!=EOF) *s++=ch; + return 1; +} inline int read(const char *s) { return read((char*)s); } +inline int readline(char *s) +{ + int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } + *s++=ch; while(ch=gch(),!(ch=='\n'||ch=='\r')&&ch!=EOF) *s++=ch; + return 1; +} inline int readline(const char *s) { return readline((char*)s); } +template inline void write(T t) +{ + int stk[20],cnt=0; + if(t==0) { wch('0'); return; } if(t<0) { wch('-'); t=-t; } + while(t>0) { stk[cnt++]=t%10; t/=10; } while(cnt) wch(stk[--cnt]+'0'); +} +inline void write(char t) { wch(t); } +inline void write(char *s) { while(*s) wch(*s++); } inline void write(const char *s) { write((char*)s); } +#if __cplusplus >= 201103L +template inline int read(T& t,Args&... args) { return read(t)+read(args...); } +template inline void write(T t,Args... args) { write(t); write(args...); } +#else +template inline int read(A_t &a,B_t &b) { return read(a)+read(b); } +template inline int read(A_t &a,B_t &b,C_t &c) { return read(a)+read(b)+read(c); } +template inline int read(A_t &a,B_t &b,C_t &c,D_t &d) { return read(a)+read(b)+read(c)+read(d); } +template inline void write(A_t a,B_t b) { write(a); write(b); } +template inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); } +template inline void write(A_t a,B_t b,C_t c,D_t d) { write(a); write(b); write(c); write(d); } +#endif +using namespace std; +typedef long long LL; +const int maxn=1e6+10; +char s[maxn]; +class SegmentTree +{ + struct Node + { + int num0; + LL IdxSumOfZero; + unsigned char InverseTag,RawData; + }buf[maxn<<3]; int NodeCnt=0; + int Length; + unsigned char mem[maxn]; + inline void PushDown(int p,LL L,LL R) + { + if(buf[p].InverseTag==0) return; + buf[p].num0=(R-L+1)-buf[p].num0; + buf[p].InverseTag=0; + buf[p].IdxSumOfZero=R*(R+1)/2-L*(L-1)/2-buf[p].IdxSumOfZero; + if(L==R) + { + buf[p].RawData^=1; + return; + } + buf[p*2].InverseTag^=1; + buf[p*2+1].InverseTag^=1; + } + inline void PushUp(int p,LL L,LL R) + { + LL M=(L+R)>>1; + buf[p].num0=(buf[p*2].InverseTag==0?buf[p*2].num0:M-L+1-buf[p*2].num0) + +(buf[p*2+1].InverseTag==0?buf[p*2+1].num0:(R-(M+1)+1)-buf[p*2+1].num0); + buf[p].IdxSumOfZero=(buf[p*2].InverseTag==0?buf[p*2].IdxSumOfZero:M*(M+1)/2-L*(L-1)/2-buf[p*2].IdxSumOfZero) + +(buf[p*2+1].InverseTag==0?buf[p*2+1].IdxSumOfZero:R*(R+1)/2-M*(M+1)/2-buf[p*2+1].IdxSumOfZero); + } + void build(int p,int L,int R) + { + assert(L<=R); + if(L==R) + { + buf[p].RawData=mem[L]; + buf[p].num0+=(mem[L]==0); + if(mem[L]==0) buf[p].IdxSumOfZero=L; + return; + } + int M=(L+R)>>1; + build(p*2,L,M); + build(p*2+1,M+1,R); + PushUp(p,L,R); + } + int QuerySinglePointStatus(int p,int L,int R,int position) + { + PushDown(p,L,R); + if(L==R) return buf[p].RawData; + int M=(L+R)>>1; + if(position<=M) return QuerySinglePointStatus(p*2,L,M,position); + else return QuerySinglePointStatus(p*2+1,M+1,R,position); + } + void InverseBlock(int p,int BL,int BR,int OL,int OR) + { + PushDown(1,BL,BR); + if(OL<=BL&&BR<=OR) + { + buf[p].InverseTag^=1; + return; + } + int M=(BL+BR)>>1; + if(OL<=M) InverseBlock(p*2,BL,M,OL,OR); + if(OR>M) InverseBlock(p*2+1,M+1,BR,OL,OR); + PushUp(p,BL,BR); + } + int QueryAllZero() + { + PushDown(1,1,Length); + return buf[1].num0; + } + LL QueryIdxSumOfZeroInRange(int p,int BL,int BR,int OL,int OR) + { + LL res=0; + PushDown(p,BL,BR); + if(OL<=BL&&BR<=OR) return buf[p].IdxSumOfZero; + int M=(BL+BR)>>1; + if(OL<=M) res+=QueryIdxSumOfZeroInRange(p*2,BL,M,OL,OR); + if(OR>M) res+=QueryIdxSumOfZeroInRange(p*2+1,M+1,BR,OL,OR); + PushUp(p,BL,BR); + return res; + } + public: + void Init(char *s,int n) + { + Length=n; + for(int i=1;i<=Length;i++) mem[i]=s[i-1]-'0'; + build(1,1,Length); + } + void InverseRange(int L,int R) + { + if(L>R) return; + // for(int i=L;i<=R;i++) mem[i]^=1; + InverseBlock(1,1,Length,L,R); + } + inline int NumberOfZero() + { + return QueryAllZero(); + // int cnt=0,tmp; + // for(int i=1;i<=Length;i++) cnt+=(mem[i]==0); + // if(tmp!=cnt) + // { + // puts("Error In NumberOfZero()"); + // printf("%d %d\n",tmp,cnt); + // } + // return cnt; + } + inline LL IdxSumOfZeroInRange(int L,int R) + { + if(L>R) return 0; + return QueryIdxSumOfZeroInRange(1,1,Length,L,R); + // LL res=0; + // for(int i=L;i<=R;i++) + // if(mem[i]==0) + // res+=i; + // return res; + } + inline LL IdxSumOfOneInRange(LL L,LL R) + { + if(L>R) return 0; + return R*(R+1)/2-L*(L-1)/2-QueryIdxSumOfZeroInRange(1,1,Length,L,R); + // LL res=0; + // for(int i=L;i<=R;i++) + // if(mem[i]==1) + // res+=i; + // return res; + } + inline char GetStatus(int position) + { + return '0'+QuerySinglePointStatus(1,1,Length,position); + // return '0'+mem[position]; + } +}SgT; +int n,m; +LL Solve() +{ + LL res=0; + int PostionOfFirstMove=SgT.NumberOfZero(); + LL Right=SgT.IdxSumOfZeroInRange(PostionOfFirstMove+1,n); + LL Left=SgT.IdxSumOfOneInRange(1,PostionOfFirstMove-1); + res=(Right-Left)*2; + if(SgT.GetStatus(PostionOfFirstMove)=='0') res+=PostionOfFirstMove; + else res-=PostionOfFirstMove; + return res; +} +int main() +{ +#ifdef local + freopen("pro.in","r",stdin); +#endif + // write(212474836480ll,'\n'); return 0; + read(n,m,s); + SgT.Init(s,n); + write(Solve(),'\n'); + for(int i=0;i +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +const int maxn=2e5+10,maxv=3e5+10; +class BST +{ + LL mem[maxv]; + public: + inline void add(int p,LL v) + { + for(;p0;p-=p&(-p)) + res+=mem[p]; + return res; + } +}num_cnt,value_tot,pre_influence; +int n,a[maxn]; +LL res=0; +int main() +{ +#ifdef local + freopen("pro.in", "r", stdin); + // freopen("pro.out","w",stdout); +#endif + scanf("%d",&n); + for(int i=1;i<=n;i++) scanf("%d",&a[i]); + for(int i=1;i<=n;i++) + { + LL delta=0; + // printf("i=%d\n",i); + delta+=LL(a[i])*num_cnt.query(maxv-1); + delta+=value_tot.query(maxv-1); + // printf("delta=%lld\n",delta); + for(int v=1,L=a[i];L +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +const LL inf=(1ll<<60); +const int maxn=1e5+10; +const int maxm=5e5+10; +struct Edge +{ + int v,w; + Edge *nxt; +}buf[maxm*2],*ECnt=buf,*G[maxn]; +inline void AddEdge(int u,int v,int w) +{ + ECnt->nxt=G[u]; + ECnt->v=v; + ECnt->w=w; + G[u]=ECnt++; +} +int n,m,s,t,g,q,h[maxn],l[maxn],TMax[maxn]; +LL dist[maxn]; +bool vis[maxn]; +struct QData +{ + int u; LL UDist; +}; +inline bool operator<(const QData &A,const QData &B) +{ + return B.UDist Q; + Q.push((QData){s,0}); + while(Q.size()) + { + int u=Q.top().u; Q.pop(); + if(vis[u]) continue; + vis[u]=true; + if(dist[u]>TMax[u]) continue; + for(Edge *it=G[u];it;it=it->nxt) + if(dist[u]+it->wv]) + { + dist[it->v]=dist[u]+it->w; + Q.push((QData){it->v,dist[it->v]}); + } + } + if(dist[t]<=g) printf("%lld\n",dist[t]); + else printf("sad\n"); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-1717.cpp b/ACMOJ-1717.cpp new file mode 100644 index 0000000..e923fc4 --- /dev/null +++ b/ACMOJ-1717.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +unordered_map cnt; +const int maxn=1e6+10; +LL res; +int n,m; +LL a[maxn]; +int main() +{ +#ifdef local + freopen("pro.in", "r", stdin); + // freopen("pro.out","w",stdout); +#endif + scanf("%d%d",&n,&m); + cnt[0]=1; + LL pre=0; + for(int i=1;i<=n;i++) + { + scanf("%lld",&a[i]); + pre^=a[i]; + res+=cnt[pre]; + cnt[pre]++; + } + for(int i=2;i<=n;i++) a[i]^=a[i-1]; + LL xor_sum=0,odd_num=0,max_res,min_res; + bool is_first=true; + while(m-->0) + { + int p,x; + scanf("%d%d",&p,&x); + LL a_before=a[p],a_after=a[p]^x; + LL delta=-(cnt[a_before]-1)+cnt[a_after]; + if(x==0) goto proc; + a[p]^=x; + cnt[a_before]--; + cnt[a_after]++; + res+=delta; + assert(res>=0); + proc: + xor_sum^=res; + odd_num+=(res&1); + if(is_first) + { + max_res=min_res=res; + is_first=false; + } + max_res=max(max_res,res); + min_res=min(min_res,res); + } + printf("%lld\n%lld\n%lld\n%lld\n",xor_sum,odd_num,max_res,min_res); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-1728.hpp b/ACMOJ-1728.hpp new file mode 100644 index 0000000..ffb9604 --- /dev/null +++ b/ACMOJ-1728.hpp @@ -0,0 +1,41 @@ +#include +#include + +void Init(int **&p, int n) { // 初始化,n为vector的个数,传入的p指向nullptr + // todo + p = new int *[n + 1]; + p[0] = new int[n + 1]; + p[0][0] = n; + for (int i = 1; i <= n; i++) p[0][i] = 1; + for (int i = 1; i <= n; i++) { + p[i] = new int[2]; + p[i][0] = 0; + } +} +void Add_element(int **&p, int x, + int y) { // 在第x(1base)个vector后面添加一个元素y + // todo + if (p[x][0] + 1 <= p[0][x]) { + p[x][0]++; + p[x][p[x][0]] = y; + } else { + int *new_p = new int[p[0][x] * 2 + 1]; + memcpy(new_p, p[x], sizeof(int) * (p[x][0] + 1)); + p[0][x] *= 2; + delete[] p[x]; + p[x] = new_p; + p[x][0]++; + p[x][p[x][0]] = y; + } +} +int Get_element(int **&p, int x, + int k) { // 获取第x(1base)个vector中第k个(1-base)元素的值 + // todo + return p[x][k]; +} +void Clear(int **&p, int n) { // 回收空间 + // todo + for (int i = 1; i <= p[0][0]; i++) delete[] p[i]; + delete[] p[0]; + delete[] p; +} \ No newline at end of file diff --git a/ACMOJ-1729.hpp b/ACMOJ-1729.hpp new file mode 100644 index 0000000..2a79516 --- /dev/null +++ b/ACMOJ-1729.hpp @@ -0,0 +1,60 @@ +#include +#include +using namespace std; + +void Init(char **&p, int n) { // 初始化,n为string的个数,传入的p指向nullptr + // todo + p = new char *[n + 1]; + p[0] = reinterpret_cast(new int[n + 1]); + for (int i = 1; i <= n; i++) reinterpret_cast(p[0])[i] = 0; + reinterpret_cast(p[0])[0] = n; + for (int i = 1; i <= n; i++) { + p[i] = new char[1]; + p[i][0] = 0; + } +} +void Assign_String(char **&p, int x, + std::string str) { // 将str赋值给第x个string + // todo + delete[] p[x]; + reinterpret_cast(p[0])[x] = str.length(); + char *new_p = new char[str.length() + 1]; + memcpy(new_p, str.c_str(), str.length() + 1); + p[x] = new_p; +} +void Merge_String( + char **&p, int x, int y, + int z) { // 把第y个string拼接到第x个string后面,赋给第z个string(x,y,z互不相等) + // (第x和y个string不变) + // todo + reinterpret_cast(p[0])[z] = + reinterpret_cast(p[0])[x] + reinterpret_cast(p[0])[y]; + delete[] p[z]; + p[z] = new char[reinterpret_cast(p[0])[z] + 1]; + memcpy(p[z], p[x], reinterpret_cast(p[0])[x]); + memcpy(p[z] + reinterpret_cast(p[0])[x], p[y], + reinterpret_cast(p[0])[y]); + p[z][reinterpret_cast(p[0])[z]] = 0; +} +void Double_String( + char **&p, int x) { // 把第x个string复制两遍前后拼接起来,再赋给第x个string + // todo + char *new_p = new char[reinterpret_cast(p[0])[x] * 2 + 1]; + memcpy(new_p, p[x], reinterpret_cast(p[0])[x]); + memcpy(new_p + reinterpret_cast(p[0])[x], p[x], + reinterpret_cast(p[0])[x]); + reinterpret_cast(p[0])[x] *= 2; + delete[] p[x]; + p[x] = new_p; + p[x][reinterpret_cast(p[0])[x]] = 0; +} +char *Get_String(char **&p, int x) { // 返回第x个string + // todo + return p[x]; +} +void Clear(char **&p, int n) { // 回收空间 + // todo + for (int i = 1; i <= n; i++) delete[] p[i]; + delete[] (reinterpret_cast(p[0])); + delete[] p; +} \ No newline at end of file diff --git a/ACMOJ-1741.cpp b/ACMOJ-1741.cpp new file mode 100644 index 0000000..11d291a --- /dev/null +++ b/ACMOJ-1741.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +using namespace std; +struct ElementType { + int r, c, p; + ElementType() {} + ElementType(int __r, int __c, int __p) : r(__r), c(__c), p(__p) {} +}; +vector res; +void Calc(int R1, int R2, int C1, int C2, int pr, int pc) { + if (R1 == R2 && C1 == C2) return; + int MR = (R1 + R2) >> 1; + int MC = (C1 + C2) >> 1; + if (pr <= MR && pc <= MC) { + res.push_back(ElementType(MR + 1, MC + 1, 1)); + Calc(R1, MR, C1, MC, pr, pc); + Calc(R1, MR, MC + 1, C2, MR, MC + 1); + Calc(MR + 1, R2, C1, MC, MR + 1, MC); + Calc(MR + 1, R2, MC + 1, C2, MR + 1, MC + 1); + return; + } + if (pr <= MR && pc > MC) { + res.push_back(ElementType(MR + 1, MC, 2)); + Calc(R1, MR, C1, MC, MR, MC); + Calc(R1, MR, MC + 1, C2, pr, pc); + Calc(MR + 1, R2, C1, MC, MR + 1, MC); + Calc(MR + 1, R2, MC + 1, C2, MR + 1, MC + 1); + return; + } + if (pr > MR && pc <= MC) { + res.push_back(ElementType(MR, MC + 1, 3)); + Calc(R1, MR, C1, MC, MR, MC); + Calc(R1, MR, MC + 1, C2, MR, MC + 1); + Calc(MR + 1, R2, C1, MC, pr, pc); + Calc(MR + 1, R2, MC + 1, C2, MR + 1, MC + 1); + return; + } + if (pr > MR && pc > MC) { + res.push_back(ElementType(MR, MC, 4)); + Calc(R1, MR, C1, MC, MR, MC); + Calc(R1, MR, MC + 1, C2, MR, MC + 1); + Calc(MR + 1, R2, C1, MC, MR + 1, MC); + Calc(MR + 1, R2, MC + 1, C2, pr, pc); + return; + } +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + int k, x, y; + scanf("%d%d%d", &k, &x, &y); + Calc(1, 1 << k, 1, 1 << k, x, y); + for (int i = 0; i < res.size(); i++) + printf("%d %d %d\n", res[i].r, res[i].c, res[i].p); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-1795.cpp b/ACMOJ-1795.cpp new file mode 100644 index 0000000..58e3861 --- /dev/null +++ b/ACMOJ-1795.cpp @@ -0,0 +1,294 @@ +#include +#include +#include +#include +#include +#include +#include +#define unlikely(x) __builtin_expect(!!(x), 0) +struct char_reader { + FILE *f; + char *buf, *p1, *p2; + int size; + char_reader(FILE *fin, int bufsize = 1 << 16) { + f = fin; + size = bufsize; + p1 = p2 = 0; + buf = new char[size]; + } + ~char_reader() { delete[] buf; } + inline int operator()() { + return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, size, f), p1 == p2) + ? EOF + : *p1++; + } +}; +struct char_writer { + FILE *f; + char *buf, *p, *end; + int size; + char_writer(FILE *fout, int bufsize = 1 << 16) { + f = fout; + size = bufsize; + buf = new char[size]; + p = buf; + end = buf + bufsize; + } + ~char_writer() { + fwrite(buf, p - buf, 1, f); + delete[] buf; + } + inline char operator()(char ch) { + if (unlikely(end == p)) { + fwrite(buf, end - buf, 1, f); + p = buf; + } + return *p++ = ch; + } +}; +char_reader gch(stdin); +char_writer wch(stdout); +template +inline int read(T &t) { + bool f = false; + int ch; + while (ch = gch(), !((ch >= '0' && ch <= '9') || ch == '-')) { + if (ch == EOF) return 0; + } + t = 0; + if (ch == '-') f = true, ch = gch(); + t = ch ^ 48; + while (ch = gch(), ch >= '0' && ch <= '9') + t = (t << 3) + (t << 1) + (ch ^ 48); + if (f) t = -t; + return 1; +} +inline int read(char &c) { + c = 0; + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + c = ch; + return 1; +} +inline int read(char *s) { + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + *s++ = ch; + while (ch = gch(), + !(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t') && ch != EOF) + *s++ = ch; + *s++ = 0; + return 1; +} +inline int read(const char *s) { return read((char *)s); } +inline int readline(char *s) { + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + *s++ = ch; + while (ch = gch(), !(ch == '\n' || ch == '\r') && ch != EOF) *s++ = ch; + *s++ = 0; + return 1; +} +inline int readline(const char *s) { return readline((char *)s); } +template +inline void write(T t) { + int stk[20], cnt = 0; + if (t == 0) { + wch('0'); + return; + } + if (t < 0) { + wch('-'); + t = -t; + } + while (t > 0) { + stk[cnt++] = t % 10; + t /= 10; + } + while (cnt) wch(stk[--cnt] + '0'); +} +inline void write(char t) { wch(t); } +inline void write(char *s) { + while (*s) wch(*s++); +} +inline void write(const char *s) { write((char *)s); } +#if __cplusplus >= 201103L +template +inline int read(T &t, Args &...args) { + return read(t) + read(args...); +} +template +inline void write(T t, Args... args) { + write(t); + write(args...); +} +#else +template +inline int read(A_t &a, B_t &b) { + return read(a) + read(b); +} +template +inline int read(A_t &a, B_t &b, C_t &c) { + return read(a) + read(b) + read(c); +} +template +inline int read(A_t &a, B_t &b, C_t &c, D_t &d) { + return read(a) + read(b) + read(c) + read(d); +} +template +inline void write(A_t a, B_t b) { + write(a); + write(b); +} +template +inline void write(A_t a, B_t b, C_t c) { + write(a); + write(b); + write(c); +} +template +inline void write(A_t a, B_t b, C_t c, D_t d) { + write(a); + write(b); + write(c); + write(d); +} +#endif +using namespace std; +typedef long long LL; +const int kMaxN = 3e5 + 100; +int trans[kMaxN][26], fail[kMaxN], node_cnt = 0; +char buf[kMaxN]; +char *s[kMaxN]; +int n, m; +LL raw_opt[kMaxN]; +void BuildACAutomaton() { + for (int i = 1; i <= n; i++) { + char *p = s[i]; + int nd = 0; + while (*p) { + if (trans[nd][*p - 'a'] == 0) trans[nd][*p - 'a'] = ++node_cnt; + nd = trans[nd][*p - 'a']; + p++; + } + } + int L = 0, R = 0; + int *Q = new int[kMaxN](); + fail[0] = -1; + Q[0] = 0; + while (L <= R) { + int u = Q[L++]; + for (int i = 0; i < 26; i++) { + if (trans[u][i] != 0) { + int v = fail[u]; + while (v != -1 && trans[v][i] == 0) v = fail[v]; + // 反复沿着失配边跳转 + if (v != -1) fail[trans[u][i]] = trans[v][i]; + // 子节点的内容在父节点就处理好 + Q[++R] = trans[u][i]; + } else if (fail[u] != -1) + trans[u][i] = trans[fail[u]][i]; + // 其余情况置0,回到初始状态 + } + } + delete[] Q; +} +struct ValContainer { + int son[kMaxN], size[kMaxN], dep[kMaxN]; + int nid[kMaxN], dfn[kMaxN], top[kMaxN]; + int data[kMaxN]; + vector G[kMaxN]; + int *fa, n, cnt; + void dfs1(int u) { + son[u] = -1; + size[u] = 1; + for (int i = G[u].size() - 1; i >= 0; --i) { + int v = G[u][i]; + dep[v] = dep[u] + 1; + dfs1(v); + if (son[u] == -1 || size[v] > size[son[u]]) son[u] = v; + } + } + void dfs2(int u, int tp) { + top[u] = tp; + cnt++; + dfn[u] = cnt; + nid[cnt] = u; + if (son[u] == -1) return; + dfs2(son[u], tp); + for (int i = G[u].size() - 1; i >= 0; i--) { + int v = G[u][i]; + if (v != son[u]) dfs2(v, v); + } + } + void Init(int __n, int *__fa) { + fa = __fa; + n = __n; + for (int i = 0; i <= node_cnt; i++) + if (fa[i] != -1) G[fa[i]].push_back(i); + dfs1(0); + dfs2(0, 0); + } + inline void __BIT_Modify(int x, int delta) { + for (; x <= cnt; x += x & (-x)) data[x] += delta; + } + inline int __BIT_Query(int x) { + int res = 0; + for (; x > 0; x -= x & (-x)) res += data[x]; + return res; + } + inline void Modify(int u, int delta) { __BIT_Modify(dfn[u], delta); } + LL Query(int u) { + LL res = 0; + int p = u; + do { + int T = top[p]; + res += __BIT_Query(dfn[p]) - __BIT_Query(dfn[T] - 1); + p = fa[T]; + } while (p >= 0); + return res; + } +} Val; +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + read(n, m); + for (int i = 1; i <= n; i++) { + read(raw_opt[i], buf); + int len = strlen(buf); + s[i] = new char[len + 5]; + for (int j = 0; j <= len; j++) s[i][j] = buf[j]; + } + BuildACAutomaton(); + Val.Init(n, fail); + LL last_ans = 0; + for (int i = 1; i <= n; i++) { + int opt = (last_ans * m) ^ (LL)raw_opt[i]; + if (opt == 1 || opt == 2) { + int delta = (opt == 1 ? 1 : -1); + int nd = 0; + char *p = s[i]; + while (*p) nd = trans[nd][(*p++) - 'a']; + Val.Modify(nd, delta); + } else if (opt == 3) { + last_ans = 0; + int nd = 0; + char *p = s[i]; + while (*p) { + nd = trans[nd][*p - 'a']; + last_ans += Val.Query(nd); + p++; + } + write(last_ans, '\n'); + } else + throw runtime_error("Unknown opt"); + } + return 0; +} \ No newline at end of file diff --git a/ACMOJ-1941.cpp b/ACMOJ-1941.cpp new file mode 100644 index 0000000..f029557 --- /dev/null +++ b/ACMOJ-1941.cpp @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include +#define unlikely(x) __builtin_expect(!!(x), 0) +struct char_reader +{ + FILE* f; char *buf,*p1,*p2; int size; + char_reader(FILE* fin,int bufsize=1<<16) { f=fin; size=bufsize; p1=p2=0; buf=new char[size]; } + ~char_reader() { delete []buf; } + inline int operator()() { return p1==p2&&(p2=(p1=buf)+fread(buf,1,size,f),p1==p2)?EOF:*p1++; } +}; +struct char_writer +{ + FILE* f; char *buf,*p,*end; int size; + char_writer(FILE* fout,int bufsize=1<<16) { f=fout; size=bufsize; buf=new char[size]; p=buf; end=buf+bufsize; } + ~char_writer() { fwrite(buf,p-buf,1,f); delete []buf; } + inline char operator()(char ch) + { + if(unlikely(end==p)) { fwrite(buf,end-buf,1,f); p=buf; } + return *p++=ch; + } +}; +char_reader gch(stdin); +char_writer wch(stdout); +template inline int read(T& t) +{ + bool f=false; int ch; while(ch=gch(),!((ch>='0'&&ch<='9')||ch=='-')) { if(ch==EOF) return 0; } + t=0; + if(ch=='-') f=true,ch=gch(); t=ch^48; while(ch=gch(),ch>='0'&&ch<='9') t=(t<<3)+(t<<1)+(ch^48); + if(f) t=-t; + return 1; +} +inline int read(char &c) +{ + c=0; int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } c=ch; + return 1; +} +inline int read(char *s) +{ + int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } + *s++=ch; while(ch=gch(),!(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')&&ch!=EOF) *s++=ch; + return 1; +} inline int read(const char *s) { return read((char*)s); } +inline int readline(char *s) +{ + int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } + *s++=ch; while(ch=gch(),!(ch=='\n'||ch=='\r')&&ch!=EOF) *s++=ch; + return 1; +} inline int readline(const char *s) { return readline((char*)s); } +template inline void write(T t) +{ + int stk[20],cnt=0; + if(t==0) { wch('0'); return; } if(t<0) { wch('-'); t=-t; } + while(t>0) { stk[cnt++]=t%10; t/=10; } while(cnt) wch(stk[--cnt]+'0'); +} +inline void write(char t) { wch(t); } +inline void write(char *s) { while(*s) wch(*s++); } inline void write(const char *s) { write((char*)s); } +#if __cplusplus >= 201103L +template inline int read(T& t,Args&... args) { return read(t)+read(args...); } +template inline void write(T t,Args... args) { write(t); write(args...); } +#else +template inline int read(A_t &a,B_t &b) { return read(a)+read(b); } +template inline int read(A_t &a,B_t &b,C_t &c) { return read(a)+read(b)+read(c); } +template inline int read(A_t &a,B_t &b,C_t &c,D_t &d) { return read(a)+read(b)+read(c)+read(d); } +template inline void write(A_t a,B_t b) { write(a); write(b); } +template inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); } +template inline void write(A_t a,B_t b,C_t c,D_t d) { write(a); write(b); write(c); write(d); } +#endif +using namespace std; +typedef long long LL; +const LL mod=998244353; +const int maxn=1e6+10; +int N,M,type,r[maxn]; +LL cnt1[2005],cnt2[2005]; +LL Factor[maxn*2]; +#define Frac(n) (Factor[n]) +LL Ksm(LL a,LL b) +{ + LL res=1,x=a; + while(b) + { + if(b&1) res=(res*x)%mod; + x=(x*x)%mod; + b>>=1; + } + return res; +} +inline LL inv(LL n) +{ + return Ksm(n,mod-2); +} +inline LL Combination(int n,int m) +{ + return (Frac(n)*inv(Frac(m)*Frac(n-m)%mod))%mod; +} +int solve0() +{ + int Blank=M; + for(int i=1;i<=N;i++) Blank-=2*r[i]-1; + if(Blank<0) return 0; + return (Frac(Blank+N)*inv(Frac(Blank)))%mod; +} +int solve1() +{ + assert(N>0); + if(N==1) return M; + LL res=0; + int Blank=M; + for(int i=1;i<=N;i++) Blank-=2*r[i]-1; + for(int i=1;i<=N;i++) cnt1[r[i]]++; + for(int i=2;i<=2000;i++) + for(int j=1;j<=i-1;j++) + cnt2[i]=(cnt2[i]+cnt1[j]*cnt1[i-j])%mod; + for(int i=1;i<=1000;i++) cnt2[i*2]-=cnt1[i]; + // for(int i=1;i<=N;i++) + // for(int j=1;j<=N;j++) + // if(i!=j&&Blank+r[i]+r[j]-2>=0) + // res=(res+Combination(Blank+N+r[i]+r[j]-2,N))%mod; + for(int i=max(2,2-Blank);i<=2000;i++) + res=(res+Combination(Blank+N+i-2,N)*cnt2[i])%mod; + res=(res*Frac(N-2))%mod; + return res; +} +int main() +{ +#ifdef local + freopen("pro.in","r",stdin); +#endif + read(N,M,type); + Factor[0]=1; + for(int i=1;i +#include +#include +#include +#include +using namespace std; +typedef long long LL; +const int inf=0x3f3f3f3f; +const int maxn=200005; +char s[maxn]; +int main() +{ +#ifdef local + freopen("pro.in","r",stdin); + // freopen("pro.out","w",stdout); +#endif + int T,n; scanf("%d",&T); + while(T-->0) + { + scanf("%s",s); n=strlen(s); + int pos[4]; + pos[1]=pos[2]=pos[3]=-1; + int res=inf; + for(int i=0;i=0) res=min(res,i-loc+1); + } + printf("%d\n",res==inf?0:res); + } + return 0; +} \ No newline at end of file diff --git a/ACMOJ-1954.cpp b/ACMOJ-1954.cpp new file mode 100644 index 0000000..fda3c20 --- /dev/null +++ b/ACMOJ-1954.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include +using namespace std; +typedef long long LL; +const int maxm=2e5+10; +struct Node +{ + int SubNode[2]; + int Cnt[4]; +}buf[maxm*50]; int NodeCnt=1,Root=1; +void AddPair(LL x,LL y,int v) +{ + const LL XorValue=x^y; + int p=Root; + for(int i=60;i>=0;i--) + { + if(buf[p].SubNode[(XorValue>>i)&1]==0) buf[p].SubNode[(XorValue>>i)&1]=++NodeCnt; + buf[p].Cnt[(((x>>i)&1)<<1)+((y>>i)&1)]+=v; + p=buf[p].SubNode[(XorValue>>i)&1]; + } +} +int query(LL x,LL y) +{ + const LL XorValue=x^y; + int res=0,p=Root; + for(int i=60;i>=0;i--) + { + if(p==0) break; + res+=buf[p].Cnt[((((x>>i)&1)^1)<<1)+((y>>i)&1)]; + p=buf[p].SubNode[(XorValue>>i)&1]; + } + return res; +} +int main() +{ +#ifdef local + freopen("pro.in","r",stdin); +#endif + int M; scanf("%d",&M); + for(int i=1;i<=M;i++) + { + int op; LL x,y; scanf("%d%lld%lld",&op,&x,&y); + if(op==1) AddPair(x,y,1); + else if(op==2) AddPair(x,y,-1); + else printf("%d\n",query(x,y)); + } + return 0; +} \ No newline at end of file diff --git a/ACMOJ-1981.cpp b/ACMOJ-1981.cpp new file mode 100644 index 0000000..364477b --- /dev/null +++ b/ACMOJ-1981.cpp @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include +#include +#define unlikely(x) __builtin_expect(!!(x), 0) +struct char_reader +{ + FILE* f; char *buf,*p1,*p2; int size; + char_reader(FILE* fin,int bufsize=1<<16) { f=fin; size=bufsize; p1=p2=0; buf=new char[size]; } + ~char_reader() { delete []buf; } + inline int operator()() { return p1==p2&&(p2=(p1=buf)+fread(buf,1,size,f),p1==p2)?EOF:*p1++; } +}; +struct char_writer +{ + FILE* f; char *buf,*p,*end; int size; + char_writer(FILE* fout,int bufsize=1<<16) { f=fout; size=bufsize; buf=new char[size]; p=buf; end=buf+bufsize; } + ~char_writer() { fwrite(buf,p-buf,1,f); delete []buf; } + inline char operator()(char ch) + { + if(unlikely(end==p)) { fwrite(buf,end-buf,1,f); p=buf; } + return *p++=ch; + } +}; +char_reader gch(stdin); +char_writer wch(stdout); +template inline int read(T& t) +{ + bool f=false; int ch; while(ch=gch(),!((ch>='0'&&ch<='9')||ch=='-')) { if(ch==EOF) return 0; } + t=0; + if(ch=='-') f=true,ch=gch(); t=ch^48; while(ch=gch(),ch>='0'&&ch<='9') t=(t<<3)+(t<<1)+(ch^48); + if(f) t=-t; + return 1; +} +inline int read(char &c) +{ + c=0; int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } c=ch; + return 1; +} +inline int read(char *s) +{ + int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } + *s++=ch; while(ch=gch(),!(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')&&ch!=EOF) *s++=ch; + return 1; +} inline int read(const char *s) { return read((char*)s); } +inline int readline(char *s) +{ + int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } + *s++=ch; while(ch=gch(),!(ch=='\n'||ch=='\r')&&ch!=EOF) *s++=ch; + return 1; +} inline int readline(const char *s) { return readline((char*)s); } +template inline void write(T t) +{ + int stk[20],cnt=0; + if(t==0) { wch('0'); return; } if(t<0) { wch('-'); t=-t; } + while(t>0) { stk[cnt++]=t%10; t/=10; } while(cnt) wch(stk[--cnt]+'0'); +} +inline void write(char t) { wch(t); } +inline void write(char *s) { while(*s) wch(*s++); } inline void write(const char *s) { write((char*)s); } +#if __cplusplus >= 201103L +template inline int read(T& t,Args&... args) { return read(t)+read(args...); } +template inline void write(T t,Args... args) { write(t); write(args...); } +#else +template inline int read(A_t &a,B_t &b) { return read(a)+read(b); } +template inline int read(A_t &a,B_t &b,C_t &c) { return read(a)+read(b)+read(c); } +template inline int read(A_t &a,B_t &b,C_t &c,D_t &d) { return read(a)+read(b)+read(c)+read(d); } +template inline void write(A_t a,B_t b) { write(a); write(b); } +template inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); } +template inline void write(A_t a,B_t b,C_t c,D_t d) { write(a); write(b); write(c); write(d); } +#endif +using namespace std; +typedef long long LL; +const int maxn=5e6+10; +const int inf=0x3f3f3f3f; +struct Edge +{ + int v; + bool deleteable; + Edge *nxt; +}buf[maxn*2],*G[maxn],*ecnt=buf; +inline void AddEdge(int u,int v) +{ + ecnt->v=v; + ecnt->nxt=G[u]; + ecnt->deleteable=false; + G[u]=ecnt++; +} +int n,m,dist[maxn]; +int main() +{ +#ifdef local + freopen("pro.in", "r", stdin); + // freopen("pro.out","w",stdout); +#endif + read(n,m); + for(int i=0;i Q; + Q.push(1); + while(Q.size()) + { + int u=Q.front(); Q.pop(); + for(Edge *it=G[u];it;it=it->nxt) + if(dist[u]+1v]) + { + dist[it->v]=dist[u]+1; + Q.push(it->v); + } + } + // for(int i=1;i<=n;i++) write("dist ",i," ",dist[i],"\n"); + for(int u=1;u<=n;u++) + { + int forward_cnt=0; + bool have_parallel=false; + for(Edge *it=G[u];it;it=it->nxt) + { + if(dist[u]==dist[it->v]) have_parallel=true; + if(dist[u]==dist[it->v]+1) forward_cnt++; + assert(abs(dist[it->v]-dist[u])<=1); + } + if(have_parallel||forward_cnt>=2) + { + // write(u," ok!\n"); + for(Edge *it=G[u];it;it=it->nxt) + { + if(dist[u]==dist[it->v]||dist[u]==dist[it->v]+1) + { + it->deleteable=true; + buf[(it-buf)^1].deleteable=true; + } + } + } + } + int res=0; + for(int i=0;i +#include +#include +#include +#include +using namespace std; +typedef long long LL; +const LL KEndStatus=123804765; +unordered_map res; +int main() +{ +#ifdef local + freopen("pro.in","r",stdin); +#endif + res[KEndStatus]=0; + queue Q; + Q.push(KEndStatus); + while(Q.size()) + { + LL u=Q.front(); Q.pop(); + int distu=res[u]; + int rid[9]={2,2,2,1,1,1,0,0,0}; + int cid[9]={2,1,0,2,1,0,2,1,0}; + int dr[4]={0,-1,0,1}; + int dc[4]={-1,0,1,0}; + int mpu[3][3],ur,uc; + LL utmp=u; + for(int i=0;i<9;i++) + { + mpu[rid[i]][cid[i]]=utmp%10; + utmp/=10; + if(mpu[rid[i]][cid[i]]==0) + { + ur=rid[i]; + uc=cid[i]; + } + } + for(int f=0;f<4;f++) + { + int vr=ur+dr[f],vc=uc+dc[f]; + if(vr==-1||vr==3||vc==-1||vc==3) continue; + swap(mpu[ur][uc],mpu[vr][vc]); + LL v=0; + for(int r=0;r<3;r++) + for(int c=0;c<3;c++) + v=v*10+mpu[r][c]; + if(v!=KEndStatus&&res[v]==0) + { + res[v]=distu+1; + Q.push(v); + } + swap(mpu[ur][uc],mpu[vr][vc]); + } + } + LL query; + scanf("%lld",&query); + printf("%d\n",res[query]); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-1999.cpp b/ACMOJ-1999.cpp new file mode 100644 index 0000000..d850f0f --- /dev/null +++ b/ACMOJ-1999.cpp @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +int T; +char mp[6][6]; +const char end_status[6][6]={ + "11111", + "01111", + "00*11", + "00001", + "00000", + " " +}; +int depth_limit; +int Evaluate() +{ + int cnt=0; + for(int i=0;i<5;i++) + for(int j=0;j<5;j++) + if(mp[i][j]!=end_status[i][j]) + cnt++; + return cnt-1; +} +bool dfs(int dep,int ur,int uc) +{ + int g=Evaluate(); + if(dep+g>depth_limit) return 0; + if(g==-1) return 1; + const int dr[]={-2,-2,-1,1,2,2,1,-1}; + const int dc[]={-1,1,2,2,1,-1,-2,-2}; + for(int i=0;i<8;i++) + { + int vr=ur+dr[i],vc=uc+dc[i]; + if(vr<0||vr>=5||vc<0||vc>=5) continue; + swap(mp[ur][uc],mp[vr][vc]); + if(dfs(dep+1,vr,vc)) return 1; + swap(mp[ur][uc],mp[vr][vc]); + } + return 0; +} +int main() +{ +#ifdef local + freopen("pro.in","r",stdin); +#endif + scanf("%d",&T); + while(T-->0) + { + for(int i=0;i<5;i++) scanf("%s",mp[i]); + int ur=-1,uc=-1; + for(int i=0;i<5;i++) + for(int j=0;j<5;j++) + if(mp[i][j]=='*') + { + ur=i; + uc=j; + break; + } + assert(ur>=0&&uc>=0); + for(depth_limit=0;depth_limit<=15;depth_limit++) + if(dfs(0,ur,uc)) + { + printf("%d\n",depth_limit); + goto nxt; + } + puts("-1"); + nxt:; + } + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2000.cpp b/ACMOJ-2000.cpp new file mode 100644 index 0000000..4cc50c9 --- /dev/null +++ b/ACMOJ-2000.cpp @@ -0,0 +1,122 @@ +#include +#include +#pragma once +#include +#define unlikely(x) __builtin_expect(!!(x), 0) +struct char_reader +{ + FILE* f; char *buf,*p1,*p2; int size; + char_reader(FILE* fin,int bufsize=1<<16) { f=fin; size=bufsize; p1=p2=0; buf=new char[size]; } + ~char_reader() { delete []buf; } + inline int operator()() { return p1==p2&&(p2=(p1=buf)+fread(buf,1,size,f),p1==p2)?EOF:*p1++; } +}; +struct char_writer +{ + FILE* f; char *buf,*p,*end; int size; + char_writer(FILE* fout,int bufsize=1<<16) { f=fout; size=bufsize; buf=new char[size]; p=buf; end=buf+bufsize; } + ~char_writer() { fwrite(buf,p-buf,1,f); delete []buf; } + inline char operator()(char ch) + { + if(unlikely(end==p)) { fwrite(buf,end-buf,1,f); p=buf; } + return *p++=ch; + } +}; +char_reader gch(stdin); +char_writer wch(stdout); +template inline int read(T& t) +{ + bool f=false; int ch; while(ch=gch(),!((ch>='0'&&ch<='9')||ch=='-')) { if(ch==EOF) return 0; } + t=0; + if(ch=='-') f=true,ch=gch(); t=ch^48; while(ch=gch(),ch>='0'&&ch<='9') t=(t<<3)+(t<<1)+(ch^48); + if(f) t=-t; + return 1; +} +inline int read(char &c) +{ + c=0; int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } c=ch; + return 1; +} +inline int read(char *s) +{ + int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } + *s++=ch; while(ch=gch(),!(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')&&ch!=EOF) *s++=ch; + return 1; +} inline int read(const char *s) { return read((char*)s); } +inline int readline(char *s) +{ + int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } + *s++=ch; while(ch=gch(),!(ch=='\n'||ch=='\r')&&ch!=EOF) *s++=ch; + return 1; +} inline int readline(const char *s) { return readline((char*)s); } +template inline void write(T t) +{ + int stk[20],cnt=0; + if(t==0) { wch('0'); return; } if(t<0) { wch('-'); t=-t; } + while(t>0) { stk[cnt++]=t%10; t/=10; } while(cnt) wch(stk[--cnt]+'0'); +} +inline void write(char t) { wch(t); } +inline void write(char *s) { while(*s) wch(*s++); } inline void write(const char *s) { write((char*)s); } +#if __cplusplus >= 201103L +template inline int read(T& t,Args&... args) { return read(t)+read(args...); } +template inline void write(T t,Args... args) { write(t); write(args...); } +#else +template inline int read(A_t &a,B_t &b) { return read(a)+read(b); } +template inline int read(A_t &a,B_t &b,C_t &c) { return read(a)+read(b)+read(c); } +template inline int read(A_t &a,B_t &b,C_t &c,D_t &d) { return read(a)+read(b)+read(c)+read(d); } +template inline void write(A_t a,B_t b) { write(a); write(b); } +template inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); } +template inline void write(A_t a,B_t b,C_t c,D_t d) { write(a); write(b); write(c); write(d); } +#endif +using namespace std; +const int maxn=1e6+10; +struct Node +{ + int val; + Node *ch[2]; +} buf[maxn*3],*ncnt=buf; +int n,fa[maxn]; +Node *Rid[maxn]; +inline int ff(int u) +{ + int rt=u,x; + while(fa[rt]!=rt) rt=fa[rt]; + while(u!=rt) + { + x=fa[u]; + fa[u]=rt; + u=x; + } + return rt; +} +void dfs(Node *rt) +{ + if(rt->ch[0]!=nullptr) dfs(rt->ch[0]); + if(rt->val!=-1) write(rt->val,' '); + if(rt->ch[1]!=nullptr) dfs(rt->ch[1]); +} +int main() +{ +#ifdef local + freopen("pro.in","r",stdin); +#endif + read(n); + for(int i=1;i<=n;i++) fa[i]=i; + for(int i=1;i<=n;i++) + { + Rid[i]=ncnt++; + Rid[i]->val=i; + } + for(int i=1;i<=n-1;i++) + { + int x,y; read(x,y); + x=ff(x); y=ff(y); + if(x==y) continue; + ncnt->ch[0]=Rid[x]; + ncnt->ch[1]=Rid[y]; + ncnt->val=-1; + fa[y]=x; + Rid[x]=ncnt++; + } + dfs(Rid[ff(1)]); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2001.cpp b/ACMOJ-2001.cpp new file mode 100644 index 0000000..413cdc2 --- /dev/null +++ b/ACMOJ-2001.cpp @@ -0,0 +1,212 @@ +#pragma once +#include +#define unlikely(x) __builtin_expect(!!(x), 0) +struct char_reader +{ + FILE* f; char *buf,*p1,*p2; int size; + char_reader(FILE* fin,int bufsize=1<<16) { f=fin; size=bufsize; p1=p2=0; buf=new char[size]; } + ~char_reader() { delete []buf; } + inline int operator()() { return p1==p2&&(p2=(p1=buf)+fread(buf,1,size,f),p1==p2)?EOF:*p1++; } +}; +struct char_writer +{ + FILE* f; char *buf,*p,*end; int size; + char_writer(FILE* fout,int bufsize=1<<16) { f=fout; size=bufsize; buf=new char[size]; p=buf; end=buf+bufsize; } + ~char_writer() { fwrite(buf,p-buf,1,f); delete []buf; } + inline char operator()(char ch) + { + if(unlikely(end==p)) { fwrite(buf,end-buf,1,f); p=buf; } + return *p++=ch; + } +}; +char_reader gch(stdin); +char_writer wch(stdout); +template inline int read(T& t) +{ + bool f=false; int ch; while(ch=gch(),!((ch>='0'&&ch<='9')||ch=='-')) { if(ch==EOF) return 0; } + t=0; + if(ch=='-') f=true,ch=gch(); t=ch^48; while(ch=gch(),ch>='0'&&ch<='9') t=(t<<3)+(t<<1)+(ch^48); + if(f) t=-t; + return 1; +} +inline int read(char &c) +{ + c=0; int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } c=ch; + return 1; +} +inline int read(char *s) +{ + int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } + *s++=ch; while(ch=gch(),!(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')&&ch!=EOF) *s++=ch; + return 1; +} inline int read(const char *s) { return read((char*)s); } +inline int readline(char *s) +{ + int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } + *s++=ch; while(ch=gch(),!(ch=='\n'||ch=='\r')&&ch!=EOF) *s++=ch; + return 1; +} inline int readline(const char *s) { return readline((char*)s); } +template inline void write(T t) +{ + int stk[20],cnt=0; + if(t==0) { wch('0'); return; } if(t<0) { wch('-'); t=-t; } + while(t>0) { stk[cnt++]=t%10; t/=10; } while(cnt) wch(stk[--cnt]+'0'); +} +inline void write(char t) { wch(t); } +inline void write(char *s) { while(*s) wch(*s++); } inline void write(const char *s) { write((char*)s); } +#if __cplusplus >= 201103L +template inline int read(T& t,Args&... args) { return read(t)+read(args...); } +template inline void write(T t,Args... args) { write(t); write(args...); } +#else +template inline int read(A_t &a,B_t &b) { return read(a)+read(b); } +template inline int read(A_t &a,B_t &b,C_t &c) { return read(a)+read(b)+read(c); } +template inline int read(A_t &a,B_t &b,C_t &c,D_t &d) { return read(a)+read(b)+read(c)+read(d); } +template inline void write(A_t a,B_t b) { write(a); write(b); } +template inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); } +template inline void write(A_t a,B_t b,C_t c,D_t d) { write(a); write(b); write(c); write(d); } +#endif +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +const int maxn=1e5+10; +const int maxm=5e5+10; +const int maxw=1e5+10; +struct DSUType +{ + int fa[maxn],size[maxn]; + void init(int n) + { + for(int i=1;i<=n;i++) + { + fa[i]=i; + size[i]=1; + } + } + inline int GetRoot(int u) + { + int rt=u,x; + while(fa[rt]!=rt) rt=fa[rt]; + while(u!=rt) + { + x=fa[u]; + fa[u]=rt; + u=x; + } + return rt; + } + inline void Merge(int a,int b) + { + a=GetRoot(a); + b=GetRoot(b); + if(size[a]b.w; } +struct Edge +{ + int v,w; + Edge *nxt; +}mem[maxm*2],*G[maxn],*ecnt=mem; +inline void AddEdge(int u,int v,int w) +{ + ecnt->v=v; + ecnt->w=w; + ecnt->nxt=G[u]; + G[u]=ecnt++; +} +int n,m; +bool vis[maxn]; +vector rawG; +int root[maxn],dep[maxn],anc[maxn][25],min_up[maxn][25]; +void InitData(int p,int fa) +{ + vis[p]=true; + dep[p]=dep[fa]+1; + for(int i=1;i<25;i++) anc[p][i]=anc[anc[p][i-1]][i-1]; + for(int i=1;i<25;i++) min_up[p][i]=min(min_up[p][i-1],min_up[anc[p][i-1]][i-1]); + for(Edge *it=G[p];it;it=it->nxt) + if(it->v!=fa) + { + min_up[it->v][0]=it->w; + anc[it->v][0]=p; + InitData(it->v,p); + } +} +inline int GetLCA(int x,int y) +{ + if(x==y) return x; + if(dep[y]>dep[x]) swap(x,y); + for(int i=24;i>=0;i--) + if(dep[anc[x][i]]>=dep[y]) + x=anc[x][i]; + assert(dep[x]==dep[y]); + if(x==y) return x; + for(int i=24;i>=0;i--) + if(anc[x][i]!=anc[y][i]) + { + x=anc[x][i]; + y=anc[y][i]; + } + return anc[x][0]; +} +inline int GetRoute(int x,int rt) +{ + int res=0x3f3f3f3f,len=dep[x]-dep[rt]; + for(int i=24;i>=0;i--) + if(len&(1< +#define unlikely(x) __builtin_expect(!!(x), 0) +struct char_reader +{ + FILE* f; char *buf,*p1,*p2; int size; + char_reader(FILE* fin,int bufsize=1<<16) { f=fin; size=bufsize; p1=p2=0; buf=new char[size]; } + ~char_reader() { delete []buf; } + inline int operator()() { return p1==p2&&(p2=(p1=buf)+fread(buf,1,size,f),p1==p2)?EOF:*p1++; } +}; +struct char_writer +{ + FILE* f; char *buf,*p,*end; int size; + char_writer(FILE* fout,int bufsize=1<<16) { f=fout; size=bufsize; buf=new char[size]; p=buf; end=buf+bufsize; } + ~char_writer() { fwrite(buf,p-buf,1,f); delete []buf; } + inline char operator()(char ch) + { + if(unlikely(end==p)) { fwrite(buf,end-buf,1,f); p=buf; } + return *p++=ch; + } +}; +char_reader gch(stdin); +char_writer wch(stdout); +template inline int read(T& t) +{ + bool f=false; int ch; while(ch=gch(),!((ch>='0'&&ch<='9')||ch=='-')) { if(ch==EOF) return 0; } + t=0; + if(ch=='-') f=true,ch=gch(); t=ch^48; while(ch=gch(),ch>='0'&&ch<='9') t=(t<<3)+(t<<1)+(ch^48); + if(f) t=-t; + return 1; +} +inline int read(char &c) +{ + c=0; int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } c=ch; + return 1; +} +inline int read(char *s) +{ + int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } + *s++=ch; while(ch=gch(),!(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')&&ch!=EOF) *s++=ch; + return 1; +} inline int read(const char *s) { return read((char*)s); } +inline int readline(char *s) +{ + int ch; while(ch=gch(),(ch==' '||ch=='\n'||ch=='\r'||ch=='\t')) { if(ch==EOF) return 0; } + *s++=ch; while(ch=gch(),!(ch=='\n'||ch=='\r')&&ch!=EOF) *s++=ch; + return 1; +} inline int readline(const char *s) { return readline((char*)s); } +template inline void write(T t) +{ + int stk[20],cnt=0; + if(t==0) { wch('0'); return; } if(t<0) { wch('-'); t=-t; } + while(t>0) { stk[cnt++]=t%10; t/=10; } while(cnt) wch(stk[--cnt]+'0'); +} +inline void write(char t) { wch(t); } +inline void write(char *s) { while(*s) wch(*s++); } inline void write(const char *s) { write((char*)s); } +#if __cplusplus >= 201103L +template inline int read(T& t,Args&... args) { return read(t)+read(args...); } +template inline void write(T t,Args... args) { write(t); write(args...); } +#else +template inline int read(A_t &a,B_t &b) { return read(a)+read(b); } +template inline int read(A_t &a,B_t &b,C_t &c) { return read(a)+read(b)+read(c); } +template inline int read(A_t &a,B_t &b,C_t &c,D_t &d) { return read(a)+read(b)+read(c)+read(d); } +template inline void write(A_t a,B_t b) { write(a); write(b); } +template inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); } +template inline void write(A_t a,B_t b,C_t c,D_t d) { write(a); write(b); write(c); write(d); } +#endif +#include +#include +#include +#include +using namespace std; +typedef long long LL; +const int maxn=5e5+10; +struct Edge +{ + int v; + Edge *nxt; +}mem[maxn*2],*G[maxn],*ecnt=mem; +inline void AddEdge(int u,int v) +{ + ecnt->v=v; + ecnt->nxt=G[u]; + G[u]=ecnt++; +} +int n,m,c[maxn],res[maxn],sub_tree_size[maxn]; +vector> query[maxn]; +struct Data +{ + vector colors; + unordered_map mp; + vector times_to_numbers; +}; +int dfs1(int u,int fa) +{ + sub_tree_size[u]=1; + for(Edge *it=G[u];it;it=it->nxt) + if(it->v!=fa) + sub_tree_size[u]+=dfs1(it->v,u); + return sub_tree_size[u]; +} +Data* dfs2(int u,int fa) +{ + // fprintf(stderr,"visit %d from %d\n",u,fa); + Data *this_data=nullptr; + if(sub_tree_size[u]==1) + { + this_data=new Data; + this_data->colors.push_back(c[u]); + this_data->mp[c[u]]=1; + this_data->times_to_numbers.push_back(0); + this_data->times_to_numbers.push_back(1); + for(int i=0;i sub_data; + int main_son=0; + assert(sub_tree_size[main_son]==0); + for(Edge *it=G[u];it;it=it->nxt) + if(it->v!=fa) + { + Data *p=dfs2(it->v,u); + if(sub_tree_size[it->v]>sub_tree_size[main_son]) + { + main_son=it->v; + swap(this_data,p); + } + if(p!=nullptr) sub_data.push_back(p); + } + for(int i=0;icolors.size();j++) + { + this_data->colors.push_back(p->colors[j]); + int tms=++this_data->mp[p->colors[j]]; + if(tms>=this_data->times_to_numbers.size()) + { + this_data->times_to_numbers.push_back(0); + // assert(tms==this_data->times_to_numbers.size()); + } + this_data->times_to_numbers[tms]++; + } + delete p; + } + this_data->colors.push_back(c[u]); + int tms=++this_data->mp[c[u]]; + if(tms>=this_data->times_to_numbers.size()) + { + this_data->times_to_numbers.push_back(0); + // assert(tms==this_data->times_to_numbers.size()); + } + this_data->times_to_numbers[tms]++; + for(int i=0;i=this_data->times_to_numbers.size()) continue; + res[id]=this_data->times_to_numbers[k]; + } + return this_data; +} +int main() +{ + #ifdef local + freopen("pro.in","r",stdin); + #endif + read(n,m); + for(int i=1;i<=n;i++) read(c[i]); + for(int i=1;i<=n-1;i++) + { + int x,y; read(x,y); + AddEdge(x,y); AddEdge(y,x); + } + for(int i=1;i<=m;i++) + { + int u,k; read(u,k); + query[u].push_back(make_pair(i,k)); + } + dfs1(1,0); + dfs2(1,0); + for(int i=1;i<=m;i++) write(res[i],'\n'); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2007.cpp b/ACMOJ-2007.cpp new file mode 100644 index 0000000..0462fe7 --- /dev/null +++ b/ACMOJ-2007.cpp @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +const double EPS = 1e-7; +struct point { + double x, y; + inline point operator+(point rhs) const { + return (point){x + rhs.x, y + rhs.y}; + } + inline point operator-(point rhs) const { + return (point){x - rhs.x, y - rhs.y}; + } + inline point operator*(double rhs) const { return (point){x * rhs, y * rhs}; } + inline double len() const { return sqrt(x * x + y * y); } +}; +inline int sgn(double x) { + if (x < -EPS) return -1; + if (x > EPS) return 1; + return 0; +} +inline double det(point x, point y) { return x.x * y.y - x.y * y.x; } +inline double dot(point x, point y) { return x.x * y.x + x.y * y.y; } +inline double dis(point x, point y) { return (x - y).len(); } +struct circle { + point c; + double r; +}; +inline bool in_circle(point p, circle c) { + return sgn(c.r - (c.c - p).len()) >= 0; +} +inline circle make_circle(point x, point y) { + return (circle){(x + y) * 0.5, (x - y).len() * 0.5}; +} +inline circle make_circle(point x, point y, point z) { + point p = y - x, q = z - x, s = (point){dot(p, p) * 0.5, dot(q, q) * 0.5}; + double d = 1.0 / det(p, q); + p = (point){det(s, (point){p.y, q.y}), det((point){p.x, q.x}, s)} * d; + return (circle){x + p, p.len()}; +} +inline circle get_circle(point x, point y, point z) { + if (sgn(det(y - x, z - x)) == 0) { + if ((x - y).len() >= (x - z).len()) { + if ((x - y).len() >= (y - z).len()) + return make_circle(x, y); + else + return make_circle(y, z); + } else { + if ((x - z).len() >= (y - z).len()) + return make_circle(x, z); + else + return make_circle(y, z); + } + } else + return make_circle(x, y, z); +} +using namespace std; +const int maxn = 1e5 + 10; +mt19937 rnd(random_device{}()); +inline int rand_less(int n) { return rnd() % n; } +int n; +point pnt[maxn]; +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + scanf("%d", &n); + for (int i = 1; i <= n; i++) scanf("%lf%lf", &pnt[i].x, &pnt[i].y); + if (n == 2) { + printf("%.8lf\n", dis(pnt[1], pnt[2]) / 2); + return 0; + } + random_shuffle(pnt + 1, pnt + 1 + n, rand_less); + circle cc = {pnt[1], 0}; + // 注意:此处不要自作聪明地初始化,必须保证一定是真正的最小圆覆盖 + for (int i = 2; i <= n; i++) { + if (in_circle(pnt[i], cc)) continue; + cc = make_circle(pnt[i], pnt[1]); + for (int j = 2; j <= i - 1; j++) { + if (in_circle(pnt[j], cc)) continue; + cc = make_circle(pnt[j], pnt[i]); + for (int k = 1; k <= j - 1; k++) { + if (in_circle(pnt[k], cc)) continue; + cc = get_circle(pnt[k], pnt[j], pnt[i]); + } + } + } + printf("%.8lf\n", cc.r); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2010.cpp b/ACMOJ-2010.cpp new file mode 100644 index 0000000..0a0c9ba --- /dev/null +++ b/ACMOJ-2010.cpp @@ -0,0 +1,330 @@ +#include +#define unlikely(x) __builtin_expect(!!(x), 0) +struct char_reader { + FILE *f; + char *buf, *p1, *p2; + int size; + char_reader(FILE *fin, int bufsize = 1 << 16) { + f = fin; + size = bufsize; + p1 = p2 = 0; + buf = new char[size]; + } + ~char_reader() { delete[] buf; } + inline int operator()() { + return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, size, f), p1 == p2) + ? EOF + : *p1++; + } +}; +struct char_writer { + FILE *f; + char *buf, *p, *end; + int size; + char_writer(FILE *fout, int bufsize = 1 << 16) { + f = fout; + size = bufsize; + buf = new char[size]; + p = buf; + end = buf + bufsize; + } + ~char_writer() { + fwrite(buf, p - buf, 1, f); + delete[] buf; + } + inline char operator()(char ch) { + if (unlikely(end == p)) { + fwrite(buf, end - buf, 1, f); + p = buf; + } + return *p++ = ch; + } +}; +char_reader gch(stdin); +char_writer wch(stdout); +template +inline int read(T &t) { + bool f = false; + int ch; + while (ch = gch(), !((ch >= '0' && ch <= '9') || ch == '-')) { + if (ch == EOF) return 0; + } + t = 0; + if (ch == '-') f = true, ch = gch(); + t = ch ^ 48; + while (ch = gch(), ch >= '0' && ch <= '9') + t = (t << 3) + (t << 1) + (ch ^ 48); + if (f) t = -t; + return 1; +} +inline int read(char &c) { + c = 0; + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + c = ch; + return 1; +} +inline int read(char *s) { + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + *s++ = ch; + while (ch = gch(), + !(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t') && ch != EOF) + *s++ = ch; + *s++ = 0; + return 1; +} +inline int read(const char *s) { return read((char *)s); } +inline int readline(char *s) { + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + *s++ = ch; + while (ch = gch(), !(ch == '\n' || ch == '\r') && ch != EOF) *s++ = ch; + *s++ = 0; + return 1; +} +inline int readline(const char *s) { return readline((char *)s); } +template +inline void write(T t) { + int stk[20], cnt = 0; + if (t == 0) { + wch('0'); + return; + } + if (t < 0) { + wch('-'); + t = -t; + } + while (t > 0) { + stk[cnt++] = t % 10; + t /= 10; + } + while (cnt) wch(stk[--cnt] + '0'); +} +inline void write(char t) { wch(t); } +inline void write(char *s) { + while (*s) wch(*s++); +} +inline void write(const char *s) { write((char *)s); } +#if __cplusplus >= 201103L +template +inline int read(T &t, Args &...args) { + return read(t) + read(args...); +} +template +inline void write(T t, Args... args) { + write(t); + write(args...); +} +#else +template +inline int read(A_t &a, B_t &b) { + return read(a) + read(b); +} +template +inline int read(A_t &a, B_t &b, C_t &c) { + return read(a) + read(b) + read(c); +} +template +inline int read(A_t &a, B_t &b, C_t &c, D_t &d) { + return read(a) + read(b) + read(c) + read(d); +} +template +inline void write(A_t a, B_t b) { + write(a); + write(b); +} +template +inline void write(A_t a, B_t b, C_t c) { + write(a); + write(b); + write(c); +} +template +inline void write(A_t a, B_t b, C_t c, D_t d) { + write(a); + write(b); + write(c); + write(d); +} +#endif +#include +#include +#include +using namespace std; +typedef long long LL; +const LL mod = 998244353; +const int maxc = 1e6 + 10; +LL ans_all = 0; +int n, m; +char **mp; +struct Node { + LL cur, sub_tree_sum; + set pos; + Node *nxt[10]; + Node() { + cur = 0; + sub_tree_sum = 0; + for (int i = 0; i < 10; i++) nxt[i] = nullptr; + } +} *const root = new Node; +void InitDfs(Node *p) { + LL delta = ((LL)n * (n + 1) / 2) % mod; + int last_pos = 0; + for (auto it = p->pos.begin(); it != p->pos.end(); ++it) { + LL gap = *it - last_pos - 1; + delta -= (gap * (gap + 1) / 2) % mod; + delta %= mod; + last_pos = *it; + } + LL gap = n - last_pos; + delta -= (gap * (gap + 1) / 2) % mod; + delta = (delta + mod) % mod; + if (p != root) { + ans_all += delta; + ans_all %= mod; + p->cur = delta; + p->sub_tree_sum = delta; + } + for (int i = 0; i < 10; i++) + if (p->nxt[i] != nullptr) { + InitDfs(p->nxt[i]); + p->sub_tree_sum += p->nxt[i]->sub_tree_sum; + p->sub_tree_sum %= mod; + } +} +void Build() { + for (int i = 1; i <= n; i++) { + Node *p = root; + for (int j = 1; j <= m; j++) { + if (p->nxt[mp[i][j] - '0'] == nullptr) p->nxt[mp[i][j] - '0'] = new Node; + p = p->nxt[mp[i][j] - '0']; + p->pos.insert(i); + } + } + InitDfs(root); +} +Node *merge_root; +void Merge(Node *dst, Node *src) { + LL delta = dst->cur; + LL change = 0; + for (auto it = src->pos.begin(); it != src->pos.end(); ++it) { + int new_pos = *it; + auto new_pos_it = dst->pos.lower_bound(new_pos); + if (*new_pos_it == new_pos) + throw "Two different string in the same position!"; + int left_pos = 0, right_pos = n + 1; + if (new_pos_it != dst->pos.begin()) { + new_pos_it--; + left_pos = *new_pos_it; + new_pos_it++; + } + if (new_pos_it != dst->pos.end()) { + right_pos = *new_pos_it; + } + LL old_gap = right_pos - left_pos - 1; + LL new_gap1 = new_pos - left_pos - 1, new_gap2 = right_pos - new_pos - 1; + delta = ((delta + old_gap * (old_gap + 1) / 2 - + new_gap1 * (new_gap1 + 1) / 2 - new_gap2 * (new_gap2 + 1) / 2) % + mod + + mod) % + mod; + dst->pos.insert(new_pos); + } + dst->sub_tree_sum -= dst->cur; + // change = delta - dst->cur; + dst->cur = delta; + dst->sub_tree_sum += dst->cur; + dst->sub_tree_sum %= mod; + // if (dst != merge_root) { + // ans_all += change; + // ans_all %= mod; + // } + bool has_covered[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + for (int i = 0; i < 10; i++) + if (src->nxt[i] != nullptr) { + has_covered[i] = true; + if (dst->nxt[i] == nullptr) { + dst->nxt[i] = new Node; + } + if (src->nxt[i]->pos.size() > dst->nxt[i]->pos.size()) { + dst->sub_tree_sum -= dst->nxt[i]->sub_tree_sum; + src->sub_tree_sum -= src->nxt[i]->sub_tree_sum; + swap(dst->nxt[i], src->nxt[i]); + dst->sub_tree_sum += dst->nxt[i]->sub_tree_sum; + src->sub_tree_sum += src->nxt[i]->sub_tree_sum; + dst->sub_tree_sum %= mod; + src->sub_tree_sum %= mod; + } + dst->sub_tree_sum -= dst->nxt[i]->sub_tree_sum; + Merge(dst->nxt[i], src->nxt[i]); + dst->sub_tree_sum += dst->nxt[i]->sub_tree_sum; + dst->sub_tree_sum %= mod; + } + for (int i = 0; i < 10; i++) + if (!has_covered[i] && dst->nxt[i] != nullptr) { + // ans_all += dst->nxt[i]->sub_tree_sum; + // ans_all %= mod; + } + delete src; +} +void Merging() { + Node *p = root; + for (int progress = 1; progress <= m - 1; progress++) { + int max_sub_size = 0, nid = -1; + for (int i = 0; i < 10; i++) + if (p->nxt[i] != nullptr) { + if (p->nxt[i]->pos.size() > max_sub_size) { + max_sub_size = p->nxt[i]->pos.size(); + nid = i; + } + } + if (max_sub_size == 0) throw "No Sub Tree!"; + bool have_things_merged = false; + for (int i = 0; i < 10; i++) + if (p->nxt[i] != nullptr && i != nid) { + merge_root = p->nxt[nid]; + Merge(p->nxt[nid], p->nxt[i]); + have_things_merged = true; + } + // if (!have_things_merged) { + // ans_all = ((ans_all - p->nxt[nid]->sub_tree_sum) % mod + mod) % mod; + for (int i = 0; i < 10; i++) + if (p->nxt[nid]->nxt[i] != nullptr) { + ans_all += p->nxt[nid]->nxt[i]->sub_tree_sum; + ans_all %= mod; + } + // } + // ans_all = (ans_all + p->nxt[nid]->sub_tree_sum) % mod; + p = p->nxt[nid]; + } +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + read(n, m); + mp = new char *[n + 2]; + for (int i = 1; i <= n; i++) mp[i] = new char[m + 3]; + for (int i = 1; i <= n; i++) { + read(mp[i] + 1); + for (int j = 1; j <= m; j++) assert('0' <= mp[i][j] && mp[i][j] <= '9'); + } + Build(); + Merging(); + ans_all = (ans_all + mod) % mod; + write(ans_all, '\n'); + return 0; +} +/* +3 2 +55 +08 +78 +*/ \ No newline at end of file diff --git a/ACMOJ-2031.cpp b/ACMOJ-2031.cpp new file mode 100644 index 0000000..4a7dc1b --- /dev/null +++ b/ACMOJ-2031.cpp @@ -0,0 +1,153 @@ +#include +#include +#include +using namespace std; +typedef long long LL; +const int L_TYPE = 0; +const int S_TYPE = 1; +namespace __SA_IS { +int a[2000100], sa[2000100], typ[2000100], c[1000100], p[2000100], + sbuc[1000100], lbuc[1000100], name[1000100]; + +inline int islms(int *typ, int i) { return !typ[i] && (i == 1 || typ[i - 1]); } + +int cmp(int *s, int *typ, int p, int q) { + do { + if (s[p] != s[q]) return 1; + p++; + q++; + } while (!islms(typ, p) && !islms(typ, q)); + return (!islms(typ, p) || !islms(typ, q) || s[p] != s[q]); +} + +void isort(int *s, int *sa, int *typ, int *c, int n, int m) { + int i; + for (lbuc[0] = sbuc[0] = c[0], i = 1; i <= m; i++) { + lbuc[i] = c[i - 1] + 1; + sbuc[i] = c[i]; + } + for (i = 1; i <= n; i++) + if (sa[i] > 1 && typ[sa[i] - 1]) sa[lbuc[s[sa[i] - 1]]++] = sa[i] - 1; + for (i = n; i >= 1; i--) + if (sa[i] > 1 && !typ[sa[i] - 1]) sa[sbuc[s[sa[i] - 1]]--] = sa[i] - 1; +} + +void build_sa(int *s, int *sa, int *typ, int *c, int *p, int n, int m) { + int i; + for (i = 0; i <= m; i++) c[i] = 0; + for (i = 1; i <= n; i++) c[s[i]]++; + for (i = 1; i <= m; i++) c[i] += c[i - 1]; + typ[n] = 0; + for (i = n - 1; i >= 1; i--) + if (s[i] < s[i + 1]) + typ[i] = 0; + else if (s[i] > s[i + 1]) + typ[i] = 1; + else + typ[i] = typ[i + 1]; + int cnt = 0; + for (i = 1; i <= n; i++) + if (!typ[i] && (i == 1 || typ[i - 1])) p[++cnt] = i; + for (i = 1; i <= n; i++) sa[i] = 0; + for (i = 0; i <= m; i++) sbuc[i] = c[i]; + for (i = 1; i <= cnt; i++) sa[sbuc[s[p[i]]]--] = p[i]; + isort(s, sa, typ, c, n, m); + int last = 0, t = -1, x; + for (i = 1; i <= n; i++) { + x = sa[i]; + if (!typ[x] && (x == 1 || typ[x - 1])) { + if (!last || cmp(s, typ, x, last)) + name[x] = ++t; + else + name[x] = t; + last = x; + } + } + for (i = 1; i <= cnt; i++) s[n + i] = name[p[i]]; + if (t < cnt - 1) + build_sa(s + n, sa + n, typ + n, c + m + 1, p + n, cnt, t); + else + for (i = 1; i <= cnt; i++) sa[n + s[n + i] + 1] = i; + for (i = 0; i <= m; i++) sbuc[i] = c[i]; + for (i = 1; i <= n; i++) sa[i] = 0; + for (i = cnt; i >= 1; i--) sa[sbuc[s[p[sa[n + i]]]]--] = p[sa[n + i]]; + isort(s, sa, typ, c, n, m); +} +} // namespace __SA_IS +void SA_IS(char *s, int n, int *sa, int *rk) { + using namespace __SA_IS; + for (int i = 1; i <= n; i++) a[i] = s[i]; + a[++n] = 0; + build_sa(a, sa, typ, c, p, n, 256); + n--; + for (int i = 1; i <= n; i++) sa[i] = sa[i + 1]; + for (int i = 1; i <= n; i++) rk[sa[i]] = i; +} +void computeHeight(char *s, int n, int *sa, int *rk, int *height) { + int k = 0; + for (int i = 1; i <= n; i++) { + if (rk[i] == 1) { + height[rk[i]] = 0; + continue; + } + if (k > 0) { + k--; + } + int j = sa[rk[i] - 1]; + while (i + k <= n && j + k <= n && s[i + k] == s[j + k]) { + k++; + } + height[rk[i]] = k; + } +} +LL GetPairMin(int *height, int n) { + int *index_stack = 1 + new int[n + 10](); + index_stack[-1] = 0; + int s_cnt = 0; + LL res = 0, cur = 0; + index_stack[s_cnt++] = 1; + for (int i = 2; i <= n; i++) { + while (s_cnt > 0 && height[index_stack[s_cnt - 1]] >= height[i]) { + s_cnt--; + cur -= (index_stack[s_cnt] - index_stack[s_cnt - 1]) * + (LL)height[index_stack[s_cnt]]; + } + index_stack[s_cnt++] = i; + cur += (index_stack[s_cnt - 1] - index_stack[s_cnt - 2]) * (LL)height[i]; + res += cur; + } + delete[] (index_stack - 1); + return res; +} +LL calc(char *s, int n) { + int *sa = new int[n << 4](); + int *rk = new int[n << 4](); + int *height = new int[n << 4](); + SA_IS(s, n, sa, rk); + computeHeight(s, n, sa, rk, height); + LL res = GetPairMin(height, n); + delete[] sa; + delete[] rk; + delete[] height; + return res; +} +const int maxn = 2e5 + 10; +char s1[maxn], s2[maxn]; +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + scanf("%s%s", s1 + 1, s2 + 1); + int n1 = strlen(s1 + 1); + int n2 = strlen(s2 + 1); + char *p = new char[n1 + n2 + 10](); + for (int i = 1; i <= n1; i++) p[i] = s1[i]; + p[n1 + 1] = 'z' + 1; + for (int i = 1; i <= n2; i++) p[n1 + 1 + i] = s2[i]; + LL ans = calc(p, n1 + 1 + n2); + ans -= calc(s1, n1); + ans -= calc(s2, n2); + delete[] p; + printf("%lld\n", ans); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2032.cpp b/ACMOJ-2032.cpp new file mode 100644 index 0000000..3e13140 --- /dev/null +++ b/ACMOJ-2032.cpp @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +const int kMaxN = 2000; +const double kEps = 1e-6; +const double kInf = 1e100; +int n, m; +char T[kMaxN], S[kMaxN]; +int fail[kMaxN], trans[kMaxN][10], tot[kMaxN], node_cnt = 0; +double val[kMaxN]; +void AddString(const char *s, double V) { + int p = 0; + while (*s) { + if (trans[p][*s - '0'] == 0) trans[p][*s - '0'] = ++node_cnt; + p = trans[p][*s - '0']; + s++; + } + tot[p]++; + val[p] += V; +} +void BuildAutomaton() { + int L = 0, R = 0; + int *Q = new int[kMaxN + 10](); + fail[0] = -1; + while (L <= R) { + int u = Q[L++]; + for (int i = 0; i < 10; i++) { + if (trans[u][i] != 0) { + int v = fail[u]; + while (v != -1 && trans[v][i] == 0) v = fail[v]; + // 反复沿着失配边跳转 + if (v != -1) fail[trans[u][i]] = trans[v][i]; + // 子节点的内容在父节点就处理好 + Q[++R] = trans[u][i]; + } else if (fail[u] != -1) + trans[u][i] = trans[fail[u]][i]; + // 其余情况置0,回到初始状态 + } + } + for (int i = 1; i <= R; i++) { + tot[Q[i]] += tot[fail[Q[i]]]; + val[Q[i]] += val[fail[Q[i]]]; + // 叠加,从贪心匹配变成匹配所有 + } + delete[] Q; +} +double dp[kMaxN][kMaxN]; +int pre_node[kMaxN][kMaxN]; +char pre_char[kMaxN][kMaxN]; +char last_ans[kMaxN]; +double calc(double v_guess) { + for (int i = 0; i <= node_cnt; i++) val[i] -= tot[i] * v_guess; + for (int i = 0; i <= n; i++) + for (int j = 0; j <= node_cnt; j++) dp[i][j] = -kInf; + dp[0][0] = 0; + for (int i = 0; i < n; i++) + for (int j = 0; j <= node_cnt; j++) { + if (dp[i][j] == -kInf) continue; + if (T[i] != '.') { + int v = trans[j][T[i] - '0']; + if (dp[i][j] + val[v] > dp[i + 1][v]) { + dp[i + 1][v] = dp[i][j] + val[v]; + pre_node[i + 1][v] = j; + pre_char[i + 1][v] = T[i]; + } + } else { + for (int k = 0; k < 10; k++) { + int v = trans[j][k]; + if (dp[i][j] + val[v] > dp[i + 1][v]) { + dp[i + 1][v] = dp[i][j] + val[v]; + pre_node[i + 1][v] = j; + pre_char[i + 1][v] = '0' + k; + } + } + } + } + for (int i = 0; i <= node_cnt; i++) val[i] += tot[i] * v_guess; + int res_pos = 0; + for (int i = 1; i <= node_cnt; i++) + if (dp[n][i] > dp[n][res_pos]) res_pos = i; + for (int str_p = n, node_p = res_pos; str_p >= 1; str_p--) { + last_ans[str_p - 1] = pre_char[str_p][node_p]; + node_p = pre_node[str_p][node_p]; + } + last_ans[n] = 0; + return dp[n][res_pos]; +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + scanf("%d%d", &n, &m); + scanf("%s", T); + for (int i = 0; i < m; i++) { + int V; + scanf("%s%d", S, &V); + AddString(S, log(V)); + } + BuildAutomaton(); + double L = 0, R = log(1e9), M, res = 0; + while (R - L > kEps) { + M = (L + R) / 2; + if (calc(M) > 0) { + res = M; + L = M; + } else + R = M; + } + calc(res); + puts(last_ans); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2033.cpp b/ACMOJ-2033.cpp new file mode 100644 index 0000000..3e34172 --- /dev/null +++ b/ACMOJ-2033.cpp @@ -0,0 +1,53 @@ +#include +#include +#include +#include +using namespace std; +typedef long long LL; +const int maxn = 1e6 + 10; +const __int128_t kBase = 114513; +const __int128_t kMod = 180143985094819841ll; +int n; +char s[maxn]; +int f[maxn]; +__int128_t kPow[maxn], hsh[maxn]; +inline bool IsSame(int L1, int R1, int L2, int R2) { + if (R1 - L1 != R2 - L2) return false; + __int128_t hsh_s1 = + ((hsh[R1] - hsh[L1 - 1] * kPow[R1 - L1 + 1]) % kMod + kMod) % kMod; + __int128_t hsh_s2 = + ((hsh[R2] - hsh[L2 - 1] * kPow[R2 - L2 + 1]) % kMod + kMod) % kMod; + return hsh_s1 == hsh_s2; +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + scanf("%d%s", &n, s + 1); + kPow[0] = 1; + for (int i = 1; i <= n; i++) { + kPow[i] = (kPow[i - 1] * kBase) % kMod; + } + for (int i = 1; i <= n; i++) { + hsh[i] = (hsh[i - 1] * kBase + s[i] - 'a' + 1) % kMod; + } + for (int i = n / 2; i > 0; i--) { + f[i] = f[i + 1] + 2; + while (f[i]) { + if ((i + f[i]) * 2 > n) + f[i]--; + else if (!IsSame(i + 1, i + f[i], n - i - f[i] + 1, n - i)) + f[i]--; + else + break; + } + } + int ans = 0; + for (int i = 1; i * 2 <= n; i++) + if (IsSame(1, i, n - i + 1, n)) { + fprintf(stderr, "find i=%d\n", i); + ans = max(ans, i + f[i]); + } + printf("%d\n", ans); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2037.cpp b/ACMOJ-2037.cpp new file mode 100644 index 0000000..8ae4546 --- /dev/null +++ b/ACMOJ-2037.cpp @@ -0,0 +1,338 @@ +#include +#include +#include +#define unlikely(x) __builtin_expect(!!(x), 0) +struct char_reader { + FILE *f; + char *buf, *p1, *p2; + int size; + char_reader(FILE *fin, int bufsize = 1 << 16) { + f = fin; + size = bufsize; + p1 = p2 = 0; + buf = new char[size]; + } + ~char_reader() { delete[] buf; } + inline int operator()() { + return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, size, f), p1 == p2) + ? EOF + : *p1++; + } +}; +struct char_writer { + FILE *f; + char *buf, *p, *end; + int size; + char_writer(FILE *fout, int bufsize = 1 << 16) { + f = fout; + size = bufsize; + buf = new char[size]; + p = buf; + end = buf + bufsize; + } + ~char_writer() { + fwrite(buf, p - buf, 1, f); + delete[] buf; + } + inline char operator()(char ch) { + if (unlikely(end == p)) { + fwrite(buf, end - buf, 1, f); + p = buf; + } + return *p++ = ch; + } +}; +char_reader gch(stdin); +char_writer wch(stdout); +template +inline int read(T &t) { + bool f = false; + int ch; + while (ch = gch(), !((ch >= '0' && ch <= '9') || ch == '-')) { + if (ch == EOF) return 0; + } + t = 0; + if (ch == '-') f = true, ch = gch(); + t = ch ^ 48; + while (ch = gch(), ch >= '0' && ch <= '9') + t = (t << 3) + (t << 1) + (ch ^ 48); + if (f) t = -t; + return 1; +} +inline int read(char &c) { + c = 0; + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + c = ch; + return 1; +} +inline int read(char *s) { + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + *s++ = ch; + while (ch = gch(), + !(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t') && ch != EOF) + *s++ = ch; + *s++ = 0; + return 1; +} +inline int read(const char *s) { return read((char *)s); } +inline int readline(char *s) { + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + *s++ = ch; + while (ch = gch(), !(ch == '\n' || ch == '\r') && ch != EOF) *s++ = ch; + *s++ = 0; + return 1; +} +inline int readline(const char *s) { return readline((char *)s); } +template +inline void write(T t) { + int stk[20], cnt = 0; + if (t == 0) { + wch('0'); + return; + } + if (t < 0) { + wch('-'); + t = -t; + } + while (t > 0) { + stk[cnt++] = t % 10; + t /= 10; + } + while (cnt) wch(stk[--cnt] + '0'); +} +inline void write(char t) { wch(t); } +inline void write(char *s) { + while (*s) wch(*s++); +} +inline void write(const char *s) { write((char *)s); } +#if __cplusplus >= 201103L +template +inline int read(T &t, Args &...args) { + return read(t) + read(args...); +} +template +inline void write(T t, Args... args) { + write(t); + write(args...); +} +#else +template +inline int read(A_t &a, B_t &b) { + return read(a) + read(b); +} +template +inline int read(A_t &a, B_t &b, C_t &c) { + return read(a) + read(b) + read(c); +} +template +inline int read(A_t &a, B_t &b, C_t &c, D_t &d) { + return read(a) + read(b) + read(c) + read(d); +} +template +inline void write(A_t a, B_t b) { + write(a); + write(b); +} +template +inline void write(A_t a, B_t b, C_t c) { + write(a); + write(b); + write(c); +} +template +inline void write(A_t a, B_t b, C_t c, D_t d) { + write(a); + write(b); + write(c); + write(d); +} +#endif +using namespace std; +typedef long long LL; +const int kMaxN = 3e5 + 10; +const LL kInf = 1e18 + 10; +int n; +char s[kMaxN]; +int sa[kMaxN * 2], rk[kMaxN * 2], height[kMaxN]; +LL a[kMaxN]; +namespace __SA_IS { +int str[kMaxN * 2], sa[kMaxN * 2], typ[kMaxN * 2], c[kMaxN], p[kMaxN * 2], + sbuc[kMaxN], lbuc[kMaxN], name[kMaxN]; + +inline int islms(int *typ, int i) { return !typ[i] && (i == 1 || typ[i - 1]); } + +int cmp(int *s, int *typ, int p, int q) { + do { + if (s[p] != s[q]) return 1; + p++; + q++; + } while (!islms(typ, p) && !islms(typ, q)); + return (!islms(typ, p) || !islms(typ, q) || s[p] != s[q]); +} + +void isort(int *s, int *sa, int *typ, int *c, int n, int m) { + int i; + for (lbuc[0] = sbuc[0] = c[0], i = 1; i <= m; i++) { + lbuc[i] = c[i - 1] + 1; + sbuc[i] = c[i]; + } + for (i = 1; i <= n; i++) + if (sa[i] > 1 && typ[sa[i] - 1]) sa[lbuc[s[sa[i] - 1]]++] = sa[i] - 1; + for (i = n; i >= 1; i--) + if (sa[i] > 1 && !typ[sa[i] - 1]) sa[sbuc[s[sa[i] - 1]]--] = sa[i] - 1; +} + +void build_sa(int *s, int *sa, int *typ, int *c, int *p, int n, int m) { + int i; + for (i = 0; i <= m; i++) c[i] = 0; + for (i = 1; i <= n; i++) c[s[i]]++; + for (i = 1; i <= m; i++) c[i] += c[i - 1]; + typ[n] = 0; + for (i = n - 1; i >= 1; i--) + if (s[i] < s[i + 1]) + typ[i] = 0; + else if (s[i] > s[i + 1]) + typ[i] = 1; + else + typ[i] = typ[i + 1]; + int cnt = 0; + for (i = 1; i <= n; i++) + if (!typ[i] && (i == 1 || typ[i - 1])) p[++cnt] = i; + for (i = 1; i <= n; i++) sa[i] = 0; + for (i = 0; i <= m; i++) sbuc[i] = c[i]; + for (i = 1; i <= cnt; i++) sa[sbuc[s[p[i]]]--] = p[i]; + isort(s, sa, typ, c, n, m); + int last = 0, t = -1, x; + for (i = 1; i <= n; i++) { + x = sa[i]; + if (!typ[x] && (x == 1 || typ[x - 1])) { + if (!last || cmp(s, typ, x, last)) + name[x] = ++t; + else + name[x] = t; + last = x; + } + } + for (i = 1; i <= cnt; i++) s[n + i] = name[p[i]]; + if (t < cnt - 1) + build_sa(s + n, sa + n, typ + n, c + m + 1, p + n, cnt, t); + else + for (i = 1; i <= cnt; i++) sa[n + s[n + i] + 1] = i; + for (i = 0; i <= m; i++) sbuc[i] = c[i]; + for (i = 1; i <= n; i++) sa[i] = 0; + for (i = cnt; i >= 1; i--) sa[sbuc[s[p[sa[n + i]]]]--] = p[sa[n + i]]; + isort(s, sa, typ, c, n, m); +} +} // namespace __SA_IS +void SA_IS(char *s, int n, int *sa, int *rk) { + using namespace __SA_IS; + for (int i = 1; i <= n; i++) str[i] = s[i]; + str[++n] = 0; + build_sa(str, sa, typ, c, p, n, 256); + n--; + for (int i = 1; i <= n; i++) sa[i] = sa[i + 1]; + for (int i = 1; i <= n; i++) rk[sa[i]] = i; +} +void computeHeight(char *s, int n, int *sa, int *rk, int *height) { + int k = 0; + for (int i = 1; i <= n; i++) { + if (rk[i] == 1) { + height[rk[i]] = 0; + continue; + } + if (k > 0) { + k--; + } + int j = sa[rk[i] - 1]; + while (i + k <= n && j + k <= n && s[i + k] == s[j + k]) { + k++; + } + height[rk[i]] = k; + } +} +LL exact_method[kMaxN], exact_yammy[kMaxN]; +struct H_Struct { + int height_index, height_value; + H_Struct() {} + H_Struct(int __h_i, int __h_v) : height_index(__h_i), height_value(__h_v) {} +}; +bool operator<(const H_Struct &A, const H_Struct &B) { + return A.height_value > B.height_value; +} +H_Struct merge_pair[kMaxN]; +int fa[kMaxN], min_a[kMaxN], max_a[kMaxN], subtree_size[kMaxN]; +LL subtree_max_yammy[kMaxN]; +inline int ff(int u) { + int v = u, x; + while (u != fa[u]) u = fa[u]; + while (v != u) { + x = fa[v]; + fa[v] = u; + v = x; + } + return u; +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + read(n); + read(s + 1); + for (int i = 1; i <= n; i++) read(a[i]); + SA_IS(s, n, sa, rk); + computeHeight(s, n, sa, rk, height); + for (int i = 2; i <= n; i++) merge_pair[i - 1] = H_Struct(i, height[i]); + sort(merge_pair + 1, merge_pair + 1 + n - 1); + for (int i = 1; i <= n; i++) { + fa[i] = i; + max_a[i] = min_a[i] = a[i]; + subtree_size[i] = 1; + subtree_max_yammy[i] = -kInf; + exact_yammy[i] = -kInf; + } + for (int i = 1; i <= n - 1; i++) { + int x = sa[merge_pair[i].height_index]; + int y = sa[merge_pair[i].height_index - 1]; + int ht = merge_pair[i].height_value; + // printf("%d and %d\n", x, y); + x = ff(x); + y = ff(y); + fa[y] = x; + exact_method[ht] += (LL)subtree_size[x] * (LL)subtree_size[y]; + // 可以归纳证明当多个height相同时,这个递推方式也是正确的 + subtree_size[x] += subtree_size[y]; + subtree_max_yammy[x] = max(subtree_max_yammy[x], subtree_max_yammy[y]); + // printf("smy %d %lld\n", x, subtree_max_yammy[x]); + subtree_max_yammy[x] = + max(subtree_max_yammy[x], + max(min_a[x] * (LL)min_a[y], max_a[x] * (LL)max_a[y])); + // printf("smy %d %lld\n", x, subtree_max_yammy[x]); + subtree_max_yammy[x] = + max(subtree_max_yammy[x], + max(max_a[x] * (LL)min_a[y], min_a[x] * (LL)max_a[y])); + // printf("smy %d %lld\n", x, subtree_max_yammy[x]); + min_a[x] = min(min_a[x], min_a[y]); + max_a[x] = max(max_a[x], max_a[y]); + // printf("mm %d %d\n", x, max_a[x]); + // printf("mi %d %d\n", x, min_a[x]); + exact_yammy[ht] = max(exact_yammy[ht], subtree_max_yammy[x]); + // 这里很显然 + } + for (int i = n - 2; i >= 0; i--) { + exact_method[i] += exact_method[i + 1]; + exact_yammy[i] = max(exact_yammy[i], exact_yammy[i + 1]); + } + for (int i = 0; i <= n - 1; i++) + printf("%lld %lld\n", exact_method[i], + exact_method[i] != 0 ? exact_yammy[i] : 0); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2045.cpp b/ACMOJ-2045.cpp new file mode 100644 index 0000000..06c7cb4 --- /dev/null +++ b/ACMOJ-2045.cpp @@ -0,0 +1,146 @@ +#include +#include +#include +using namespace std; +typedef long long LL; +const int L_TYPE = 0; +const int S_TYPE = 1; +const int maxn = 1e6 + 10; +int n; +char s[maxn]; +namespace __SA_IS { +int a[2000100], sa[2000100], typ[2000100], c[1000100], p[2000100], + sbuc[1000100], lbuc[1000100], name[1000100]; + +inline int islms(int *typ, int i) { return !typ[i] && (i == 1 || typ[i - 1]); } + +int cmp(int *s, int *typ, int p, int q) { + do { + if (s[p] != s[q]) return 1; + p++; + q++; + } while (!islms(typ, p) && !islms(typ, q)); + return (!islms(typ, p) || !islms(typ, q) || s[p] != s[q]); +} + +void isort(int *s, int *sa, int *typ, int *c, int n, int m) { + int i; + for (lbuc[0] = sbuc[0] = c[0], i = 1; i <= m; i++) { + lbuc[i] = c[i - 1] + 1; + sbuc[i] = c[i]; + } + for (i = 1; i <= n; i++) + if (sa[i] > 1 && typ[sa[i] - 1]) sa[lbuc[s[sa[i] - 1]]++] = sa[i] - 1; + for (i = n; i >= 1; i--) + if (sa[i] > 1 && !typ[sa[i] - 1]) sa[sbuc[s[sa[i] - 1]]--] = sa[i] - 1; +} + +void build_sa(int *s, int *sa, int *typ, int *c, int *p, int n, int m) { + int i; + for (i = 0; i <= m; i++) c[i] = 0; + for (i = 1; i <= n; i++) c[s[i]]++; + for (i = 1; i <= m; i++) c[i] += c[i - 1]; + typ[n] = 0; + for (i = n - 1; i >= 1; i--) + if (s[i] < s[i + 1]) + typ[i] = 0; + else if (s[i] > s[i + 1]) + typ[i] = 1; + else + typ[i] = typ[i + 1]; + int cnt = 0; + for (i = 1; i <= n; i++) + if (!typ[i] && (i == 1 || typ[i - 1])) p[++cnt] = i; + for (i = 1; i <= n; i++) sa[i] = 0; + for (i = 0; i <= m; i++) sbuc[i] = c[i]; + for (i = 1; i <= cnt; i++) sa[sbuc[s[p[i]]]--] = p[i]; + isort(s, sa, typ, c, n, m); + int last = 0, t = -1, x; + for (i = 1; i <= n; i++) { + x = sa[i]; + if (!typ[x] && (x == 1 || typ[x - 1])) { + if (!last || cmp(s, typ, x, last)) + name[x] = ++t; + else + name[x] = t; + last = x; + } + } + for (i = 1; i <= cnt; i++) s[n + i] = name[p[i]]; + if (t < cnt - 1) + build_sa(s + n, sa + n, typ + n, c + m + 1, p + n, cnt, t); + else + for (i = 1; i <= cnt; i++) sa[n + s[n + i] + 1] = i; + for (i = 0; i <= m; i++) sbuc[i] = c[i]; + for (i = 1; i <= n; i++) sa[i] = 0; + for (i = cnt; i >= 1; i--) sa[sbuc[s[p[sa[n + i]]]]--] = p[sa[n + i]]; + isort(s, sa, typ, c, n, m); +} +} // namespace __SA_IS +void SA_IS(char *s, int n, int *sa, int *rk) { + using namespace __SA_IS; + for (int i = 1; i <= n; i++) a[i] = s[i]; + a[++n] = 0; + build_sa(a, sa, typ, c, p, n, 256); + n--; + for (int i = 1; i <= n; i++) sa[i] = sa[i + 1]; + for (int i = 1; i <= n; i++) rk[sa[i]] = i; +} +void computeHeight(char *s, int n, int *sa, int *rk, int *height) { + int k = 0; + for (int i = 1; i <= n; i++) { + if (rk[i] == 1) { + height[rk[i]] = 0; + continue; + } + if (k > 0) { + k--; + } + int j = sa[rk[i] - 1]; + while (i + k <= n && j + k <= n && s[i + k] == s[j + k]) { + k++; + } + height[rk[i]] = k; + } +} +LL GetPairMin(int *height, int n) { + int *index_stack = 1 + new int[n + 10](); + index_stack[-1] = 0; + int s_cnt = 0; + LL res = 0, cur = 0; + index_stack[s_cnt++] = 1; + for (int i = 2; i <= n; i++) { + while (s_cnt > 0 && height[index_stack[s_cnt - 1]] >= height[i]) { + s_cnt--; + cur -= (index_stack[s_cnt] - index_stack[s_cnt - 1]) * + (LL)height[index_stack[s_cnt]]; + } + index_stack[s_cnt++] = i; + cur += (index_stack[s_cnt - 1] - index_stack[s_cnt - 2]) * (LL)height[i]; + res += cur; + } + delete[] (index_stack - 1); + return res; +} +LL calc(char *s, int n) { + int *sa = new int[n << 4](); + int *rk = new int[n << 4](); + int *height = new int[n << 4](); + SA_IS(s, n, sa, rk); + computeHeight(s, n, sa, rk, height); + LL res = 0; + for (int i = 1; i <= n; i++) res += n + 1 - sa[i] - height[i]; + delete[] sa; + delete[] rk; + delete[] height; + return res; +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + scanf("%d%s", &n, s + 1); + LL res = calc(s, n); + printf("%lld\n", res); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2050.cpp b/ACMOJ-2050.cpp new file mode 100644 index 0000000..3cb68d6 --- /dev/null +++ b/ACMOJ-2050.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +using namespace std; +typedef long long LL; +const int kMaxn = 1e5 + 10; +int n, m, c[kMaxn * 2], res[kMaxn], cnt; +inline void Modify(int p, int v) { + for (; p <= m; p += p & (-p)) c[p] += v; +} +inline int Query(int p) { + int res = 0; + for (; p > 0; p -= p & (-p)) res += c[p]; + return res; +} +struct Data { + int a, b, c, w, f; +}; +Data val[kMaxn], tmp[kMaxn]; +bool cmp(const Data &x, const Data &y) { + if (x.a != y.a) return x.a < y.a; + if (x.b != y.b) return x.b < y.b; + return x.c < y.c; +} +void CDQ(int L, int R) { + if (L == R) return; + int M = (L + R) >> 1; + CDQ(L, M); + CDQ(M + 1, R); + int p = L, q = M + 1, d = L; + while (p <= M && q <= R) { + if (val[p].b <= val[q].b) { + Modify(val[p].c, val[p].w); + tmp[d++] = val[p++]; + } else { + val[q].f += Query(val[q].c); + tmp[d++] = val[q++]; + } + } + while (p <= M) { + Modify(val[p].c, val[p].w); + tmp[d++] = val[p++]; + } + while (q <= R) { + val[q].f += Query(val[q].c); + tmp[d++] = val[q++]; + } + for (int i = L; i <= M; i++) Modify(val[i].c, -val[i].w); + for (int i = L; i <= R; i++) val[i] = tmp[i]; +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + scanf("%d%d", &n, &m); + for (int i = 1; i <= n; i++) { + scanf("%d%d%d", &val[i].a, &val[i].b, &val[i].c); + val[i].w = 1; + } + sort(val + 1, val + 1 + n, cmp); + cnt = 1; + for (int i = 2; i <= n; i++) { + if (val[i].a == val[cnt].a && val[i].b == val[cnt].b && + val[i].c == val[cnt].c) + val[cnt].w++; + else + val[++cnt] = val[i]; + } + CDQ(1, cnt); + for (int i = 1; i <= cnt; i++) res[val[i].f + val[i].w - 1] += val[i].w; + for (int i = 0; i < n; i++) printf("%d\n", res[i]); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2057.cpp b/ACMOJ-2057.cpp new file mode 100644 index 0000000..b6612dc --- /dev/null +++ b/ACMOJ-2057.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +using namespace std; +typedef long long LL; +const int kMaxn = 1e5 + 10; +const int kMaxv = 1e5; +int n, m; +int a[kMaxn], max_d[kMaxn], min_d[kMaxn]; +int f[kMaxn], res, pos[kMaxn]; +bool cmp_max_d(int a, int b) { return max_d[a] < max_d[b]; } +bool cmp_a(int x, int y) { return a[x] < a[y]; } +int val[kMaxn]; +void Modify(int p, int v) { + for (; p <= kMaxv; p += p & (-p)) val[p] = max(val[p], v); +} +int Query(int p) { + int res = 0; + for (; p > 0; p -= p & (-p)) res = max(res, val[p]); + return res; +} +void Clear(int p) { + for (; p <= kMaxv; p += p & (-p)) val[p] = 0; +} +void CDQ(int L, int R) { + if (L == R) { + f[L] = max(f[L], 1); + return; + } + int M = (L + R) >> 1; + CDQ(L, M); + for (int i = L; i <= R; i++) pos[i] = i; + sort(pos + L, pos + M + 1, cmp_max_d); + sort(pos + M + 1, pos + R + 1, cmp_a); + int pl = L; + for (int pr = M + 1; pr <= R; pr++) { + while (pl <= M && max_d[pos[pl]] <= a[pos[pr]]) { + Modify(a[pos[pl]], f[pos[pl]]); + pl++; + } + f[pos[pr]] = max(f[pos[pr]], Query(min_d[pos[pr]]) + 1); + } + for (int i = L; i <= M; i++) Clear(a[i]); + CDQ(M + 1, R); +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + scanf("%d%d", &n, &m); + for (int i = 1; i <= n; i++) { + scanf("%d", &a[i]); + max_d[i] = a[i]; + min_d[i] = a[i]; + } + for (int i = 1; i <= m; i++) { + int x, y; + scanf("%d%d", &x, &y); + max_d[x] = max(max_d[x], y); + min_d[x] = min(min_d[x], y); + } + CDQ(1, n); + for (int i = 1; i <= n; i++) res = max(res, f[i]); + printf("%d\n", res); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2058.cpp b/ACMOJ-2058.cpp new file mode 100644 index 0000000..254257b --- /dev/null +++ b/ACMOJ-2058.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +using namespace std; +typedef long long LL; +const int kMaxn = 1e5 + 10; +const LL kInf = 1e18; +LL f[kMaxn]; +int n, w[kMaxn]; +struct Data { + int x, oid; + LL y; +} val[kMaxn], tmp[kMaxn]; +double Slope(int a, int b) { + if (val[a].x == val[b].x) { + return val[a].y < val[b].y ? kInf : -kInf; + } + return double(val[b].y - val[a].y) / double(val[b].x - val[a].x); +} +void CDQ(int L, int R) { + if (L == R) { + val[L].y = f[val[L].oid] + val[L].x * (LL)val[L].x; + // printf("y(%d)=%d\n",L,val[L].y); + return; + } + int M = (L + R) >> 1; + for (int i = L, pl = L, pr = M + 1; i <= R; i++) { + if (val[i].oid <= M) { + tmp[pl++] = val[i]; + } else { + tmp[pr++] = val[i]; + } + } + for (int i = L; i <= R; i++) val[i] = tmp[i]; + CDQ(L, M); + int *Q = new int[R - L + 100](), QL = 1, QR = 0; + for (int i = L; i <= M; i++) { + while (QL < QR && Slope(Q[QR - 1], Q[QR]) > Slope(Q[QR], i)) + QR--; + Q[++QR] = i; + } + for (int i = M + 1; i <= R; i++) { + while (QL < QR && Slope(Q[QL], Q[QL + 1]) < 2 * val[i].x) QL++; + int x = val[i].oid, y = val[Q[QL]].oid; + f[x] = min(f[x], f[y] - w[x] + + (val[i].x - val[Q[QL]].x) * (LL)(val[i].x - val[Q[QL]].x)); + } + CDQ(M + 1, R); + for (int i = L, pl = L, pr = M + 1; i <= R; i++) { + if (pr > R || (pl <= M && val[pl].x < val[pr].x)) + tmp[i] = val[pl++]; + else + tmp[i] = val[pr++]; + } + for (int i = L; i <= R; i++) val[i] = tmp[i]; + delete[] Q; +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + scanf("%d", &n); + for (int i = 1; i <= n; i++) { + scanf("%d", &val[i].x); + val[i].oid = i; + f[i] = kInf * 4; + } + f[1] = 0; + for (int i = 1; i <= n; i++) { + scanf("%d", &w[i]); + if (i >= 2) f[1] += w[i]; + } + sort(val + 1, val + 1 + n, + [](const Data &a, const Data &b) { return a.x < b.x; }); + CDQ(1, n); + printf("%lld\n", f[n]); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2059.h b/ACMOJ-2059.h new file mode 100644 index 0000000..a34dd4a --- /dev/null +++ b/ACMOJ-2059.h @@ -0,0 +1,86 @@ +#include +#include +#include + +class Student { + public: + static std::map id2student; + static std::map name2student; + enum class Gender { Boy, Girl }; + + private: + int id; + std::string name; + int age; + Gender gender; + + public: + // 从输入流构造 + // 输入格式与输出格式一致 + // 输出函数已给出 + Student(std::istream &is) { + std::string tmp_gender; + is >> id >> name >> age >> tmp_gender; + if (tmp_gender == "boy") + gender = Gender::Boy; + else + gender = Gender::Girl; + id2student[id] = this; + name2student[name] = this; + } + + // 人无法被复制(至少不应该) + Student(Student const &rhs) = delete; + Student &operator=(Student const &rhs) = delete; + // 你需要支持的操作 + Student(Student &&rhs) { + id = rhs.id; + name = rhs.name; + age = rhs.age; + gender = rhs.gender; + rhs.id = 0; + id2student[id] = this; + name2student[name] = this; + } + Student &operator=(Student &&rhs) { + if ((&rhs) != this) { + if (id != 0) { + id2student.erase(id); + name2student.erase(name); + } + id = rhs.id; + name = rhs.name; + age = rhs.age; + gender = rhs.gender; + rhs.id = 0; + id2student[id] = this; + name2student[name] = this; + } + return *this; + } + ~Student() { + if (id != 0) { + id2student.erase(id); + name2student.erase(name); + } + } + + Student &rename(std::string const &str) & { + name2student.erase(name); + name = str; + name2student[name] = this; + return *this; + } + Student rename(std::string const &str) && { + name2student.erase(name); + name = str; + name2student[name] = this; + Student tmp(std::move(*this)); + return std::move(tmp); + } + + friend std::ostream &operator<<(std::ostream &os, Student &stu) { + return os << stu.id << ' ' << stu.name << ' ' << stu.age << ' ' + << (stu.gender == Student::Gender::Boy ? "boy" : "girl"); + } +}; \ No newline at end of file diff --git a/ACMOJ-2065.cpp b/ACMOJ-2065.cpp new file mode 100644 index 0000000..82f4e39 --- /dev/null +++ b/ACMOJ-2065.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +#include +using namespace std; +typedef long long LL; +const int kMaxn = 2e5 + 10; +struct DataType { + int r, y; + int uid, dfn, boundary; +} val[kMaxn], tmp[kMaxn]; +vector G[kMaxn]; +int n, dfn_cnt, res[kMaxn]; +void PreWork(int u, int fa) { + val[u].dfn = ++dfn_cnt; + for (int v : G[u]) { + if (v == fa) continue; + PreWork(v, u); + } + val[u].boundary = dfn_cnt; +} +class BSTType { + LL data[kMaxn]; + int len = 0; + + public: + void Init(int n) { len = n; } + void Modify(int p, int v) { + for (; p <= len; p += p & (-p)) data[p] += v; + } + LL Query(int p) { + LL res = 0; + for (; p > 0; p -= p & (-p)) res += data[p]; + return res; + } +} BST; +void CDQ(int L, int R) { + if (L == R) return; + int M = (L + R) >> 1; + CDQ(L, M); + CDQ(M + 1, R); + sort(val + L, val + M + 1, + [](const DataType &A, const DataType &B) { return A.r < B.r; }); + sort(val + M + 1, val + R + 1, + [](const DataType &A, const DataType &B) { return A.r < B.r; }); + int pl = L, pr = M + 1; + while (pr <= R) { + while (pl <= M && val[pl].r <= val[pr].r) BST.Modify(val[pl++].dfn, 1); + res[val[pr].uid] += BST.Query(val[pr].boundary) - BST.Query(val[pr].dfn); + pr++; + } + for (int i = L; i < pl; i++) BST.Modify(val[i].dfn, -1); +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + scanf("%d", &n); + for (int i = 1; i <= n - 1; i++) { + int u, v; + scanf("%d%d", &u, &v); + G[u].push_back(v); + G[v].push_back(u); + } + for (int i = 1; i <= n; i++) { + scanf("%d%d", &val[i].r, &val[i].y); + val[i].uid = i; + } + PreWork(1, 0); + BST.Init(n); + sort(val + 1, val + 1 + n, [](const DataType &A, const DataType &B) { + return A.y != B.y ? A.y < B.y : (A.r != B.r ? A.r < B.r : A.dfn > B.dfn); + }); + CDQ(1, n); + for (int i = 1; i <= n; i++) + if (res[i] != 0) printf("%d\n", res[i]); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2069.hpp b/ACMOJ-2069.hpp new file mode 100644 index 0000000..254312c --- /dev/null +++ b/ACMOJ-2069.hpp @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include + +struct dynamic_bitset { + int len = 0; + typedef unsigned long long ULL; + std::vector val; + dynamic_bitset() noexcept = default; + + ~dynamic_bitset() noexcept = default; + + dynamic_bitset(const dynamic_bitset &) noexcept = default; + + dynamic_bitset &operator=(const dynamic_bitset &) noexcept = default; + + dynamic_bitset(std::size_t n) noexcept { + len = n; + val.resize((n + 63) / 64); + for (int i = (n + 63) / 64 - 1; i >= 0; i--) val[i] = 0; + } + + dynamic_bitset(const std::string &str) noexcept { + len = str.size(); + val.resize((len + 63) / 64); + for (int i = 0; i < val.size(); i++) val[i] = 0; + for (int i = 0; i < len; i++) + val[i / 64] |= ((1ull * (str[i] - '0')) << (i % 64)); + } + + inline bool operator[](std::size_t n) const noexcept { + return (val[n / 64] & (1ull << (n % 64))) != 0; + } + + dynamic_bitset &set(std::size_t n, bool __val = true) noexcept { + val[n / 64] &= ULL(-1) ^ (1ull << (n % 64)); + val[n / 64] |= ((1ull * __val) << (n % 64)); + return *this; + } + + dynamic_bitset &push_back(bool __val) noexcept { + len++; + if (len % 64 == 1) + val.push_back((ULL)__val); + else + val[(len - 1) / 64] |= ((1ull * __val) << ((len - 1) % 64)); + return *this; + } + + bool none() const noexcept { + for (int i = 0; i < val.size(); i++) + if (val[i] != 0) return false; + return true; + } + + bool all() const noexcept { + for (int i = 0; i < val.size() - 1; i++) + if (val[i] != ULL(-1)) return false; + if (val[val.size() - 1] != + ULL((1ull << (len % 64 == 0 ? 64 : len % 64)) - 1)) + return false; + return true; + } + + inline std::size_t size() const noexcept { return len; } + + dynamic_bitset &operator|=(const dynamic_bitset &B) noexcept { + int op_len = std::min(len, B.len); + int op_buckets = (op_len + 63) / 64; + for (int i = 0; i < op_buckets - 1; i++) val[i] |= B.val[i]; + val[op_buckets - 1] |= + (ULL((1ull << (op_len % 64 == 0 ? 64 : op_len % 64)) - 1ll)) & + B.val[op_buckets - 1]; + return *this; + } + + dynamic_bitset &operator&=(const dynamic_bitset &B) noexcept { + int op_len = std::min(len, B.len); + int op_buckets = (op_len + 63) / 64; + for (int i = 0; i < op_buckets - 1; i++) val[i] &= B.val[i]; + val[op_buckets - 1] &= + (~ULL((1ull << (op_len % 64 == 0 ? 64 : op_len % 64)) - 1ll)) | + B.val[op_buckets - 1]; + return *this; + } + + dynamic_bitset &operator^=(const dynamic_bitset &B) noexcept { + int op_len = std::min(len, B.len); + int op_buckets = (op_len + 63) / 64; + for (int i = 0; i < op_buckets - 1; i++) val[i] ^= B.val[i]; + val[op_buckets - 1] ^= + (ULL((1ull << (op_len % 64 == 0 ? 64 : op_len % 64)) - 1ll)) & + B.val[op_buckets - 1]; + return *this; + } + + dynamic_bitset &operator<<=(std::size_t n) noexcept { + int big_move = n / 64, small_move = n % 64; + int ors = val.size(); + val.resize((n + len + 63) / 64); + int obn = val.size(); + if (small_move == 0) { + std::memmove(val.data() + big_move, val.data(), sizeof(ULL) * ors); + std::memset(val.data(), 0, sizeof(ULL) * std::min(big_move, ors)); + } else { + for (int i = (n + len + 63) / 64 - 1; i >= big_move; i--) { + val[i] = (((i - big_move >= 0 && i - big_move < obn ? val[i - big_move] + : 0) & + ULL(((1ull << (64 - small_move))) - 1)) + << small_move) | + ((i - big_move - 1 >= 0 ? val[i - big_move - 1] : 0) >> + (64 - small_move)); + } + std::memset(val.data(), 0, sizeof(ULL) * std::min(big_move, ors)); + } + len += n; + return *this; + } + + dynamic_bitset &operator>>=(std::size_t n) noexcept { + if (n > len) n = len; + int big_move = n / 64, small_move = n % 64; + int obn = val.size(); + if (small_move == 0) { + for (int i = 0; i < (len - n + 63) / 64; i++) { + val[i] = (i + big_move < obn ? val[i + big_move] : 0); + } + } else { + for (int i = 0; i < (len - n + 63) / 64; i++) { + val[i] = ((i + big_move < obn ? val[i + big_move] : 0) >> small_move) | + ((i + big_move + 1 < obn ? val[i + big_move + 1] : 0) + << (64 - small_move)); + } + } + len -= n; + val.resize((len + 63) / 64); + if (val.size() > 0) + val[val.size() - 1] &= + ULL((1ull << (len % 64 == 0 ? 64 : len % 64)) - 1ll); + return *this; + } + + dynamic_bitset &set() noexcept { + if (len == 0) return *this; + std::memset(val.data(), -1, sizeof(ULL) * val.size()); + val[val.size() - 1] = ULL((1ull << (len % 64 == 0 ? 64 : len % 64)) - 1ll); + return *this; + } + + dynamic_bitset &flip() noexcept { + if (len == 0) return *this; + for (int i = 0; i < val.size() - 1; i++) val[i] = ~val[i]; + val[val.size() - 1] ^= ULL((1ull << (len % 64 == 0 ? 64 : len % 64)) - 1ll); + return *this; + } + + dynamic_bitset &reset() noexcept { + if (len == 0) return *this; + std::memset(val.data(), 0, sizeof(ULL) * val.size()); + return *this; + } +}; \ No newline at end of file diff --git a/ACMOJ-2073.cpp b/ACMOJ-2073.cpp new file mode 100644 index 0000000..471688a --- /dev/null +++ b/ACMOJ-2073.cpp @@ -0,0 +1,17 @@ +#include "ACMOJ-2073.hpp" + +#include +#include +#include +using namespace std; +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + // 可以试着玩玩 sjtu::make_string 函数 + const auto data = sjtu::make_string(114ll, std::string("514"), 19, "810"); + for (auto &x : data) std::cout << x << '\n'; + std::cout << sjtu::format("{0}{1}, {2}{2}{3}!\n", 114ll, std::string("514"), + 19, "810"); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2073.hpp b/ACMOJ-2073.hpp new file mode 100644 index 0000000..89d5b63 --- /dev/null +++ b/ACMOJ-2073.hpp @@ -0,0 +1,95 @@ +// 你需要在代码中 #include "utility.h" +// 你可以使用这个模板库的函数 +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "utility.h" +namespace sjtu { + +template +std::string format(std::string_view fmt, Args &&...args) { + std::vector vec = make_string(std::forward(args)...); + std::string ret; + std::vector arg_seq; + std::vector str_seq; + std::stack stk; + std::stringstream ss; + std::stringstream pos_ss; + for (int i = 0; i < fmt.length(); i++) { + if (fmt[i] == '{') { + if (stk.size() >= 2) throw std::runtime_error("invalid format string"); + if (stk.size() == 0) + stk.push(i); + else { + int pl = stk.top(); + stk.pop(); + if (pl + 1 == i) { + ss << '{'; + } else + throw std::runtime_error("invalid format string"); + } + } else if (fmt[i] == '}') { + if (stk.size() != 1) throw std::runtime_error("invalid format string"); + stk.pop(); + str_seq.emplace_back(""); + str_seq[str_seq.size() - 1] = ss.str(); + // std::cerr << "get str token: " << str_seq[str_seq.size() - 1] + // << std::endl; + int ps = -1; + if (!(pos_ss >> ps)) ps = -1; + arg_seq.emplace_back(ps); + ss.clear(); + ss.str(""); + pos_ss.clear(); + pos_ss.str(""); + } else { + if (stk.size() >= 2) throw std::runtime_error("invalid format string"); + if (stk.size() == 0) + ss << fmt[i]; + else { + if (fmt[i] < '0' || fmt[i] > '9') + throw std::runtime_error("invalid format string"); + pos_ss << fmt[i]; + } + } + } + std::string tmp; + tmp = ss.str(); + str_seq.emplace_back(tmp); + ss.clear(); + ss.str(""); + bool auto_pos = true; + for (int i = 0; i < arg_seq.size(); i++) { + if (arg_seq[i] >= 0) auto_pos = false; + } + for (int i = 0; i < arg_seq.size(); i++) { + if (auto_pos && arg_seq[i] >= 0) + throw std::runtime_error("invalid format string"); + if ((!auto_pos) && arg_seq[i] == -1) + throw std::runtime_error("invalid format string"); + } + // std::cerr << "argsize=" << arg_seq.size() << std::endl; + // std::cerr << "str_size=" << str_seq.size() << std::endl; + if (auto_pos) + for (int i = 0; i < arg_seq.size(); i++) { + arg_seq[i] = i; + } + for (int i = 0; i < arg_seq.size(); i++) { + if (arg_seq[i] >= vec.size()) + throw std::runtime_error("invalid format string"); + } + for (int i = 0; i < arg_seq.size(); i++) { + ss << str_seq[i]; + ss << vec[arg_seq[i]]; + } + ss << str_seq[str_seq.size() - 1]; + ret = ss.str(); + return ret; +} +} // namespace sjtu \ No newline at end of file diff --git a/ACMOJ-2080.cpp b/ACMOJ-2080.cpp new file mode 100644 index 0000000..bf50fb6 --- /dev/null +++ b/ACMOJ-2080.cpp @@ -0,0 +1,193 @@ +#include +#define unlikely(x) __builtin_expect(!!(x), 0) +struct char_reader { + FILE *f; + char *buf, *p1, *p2; + int size; + char_reader(FILE *fin, int bufsize = 1 << 16) { + f = fin; + size = bufsize; + p1 = p2 = 0; + buf = new char[size]; + } + ~char_reader() { delete[] buf; } + inline int operator()() { + return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, size, f), p1 == p2) + ? EOF + : *p1++; + } +}; +struct char_writer { + FILE *f; + char *buf, *p, *end; + int size; + char_writer(FILE *fout, int bufsize = 1 << 16) { + f = fout; + size = bufsize; + buf = new char[size]; + p = buf; + end = buf + bufsize; + } + ~char_writer() { + fwrite(buf, p - buf, 1, f); + delete[] buf; + } + inline char operator()(char ch) { + if (unlikely(end == p)) { + fwrite(buf, end - buf, 1, f); + p = buf; + } + return *p++ = ch; + } +}; +char_reader gch(stdin); +char_writer wch(stdout); +template +inline int read(T &t) { + bool f = false; + int ch; + while (ch = gch(), !((ch >= '0' && ch <= '9') || ch == '-')) { + if (ch == EOF) return 0; + } + t = 0; + if (ch == '-') f = true, ch = gch(); + t = ch ^ 48; + while (ch = gch(), ch >= '0' && ch <= '9') + t = (t << 3) + (t << 1) + (ch ^ 48); + if (f) t = -t; + return 1; +} +inline int read(char &c) { + c = 0; + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + c = ch; + return 1; +} +inline int read(char *s) { + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + *s++ = ch; + while (ch = gch(), + !(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t') && ch != EOF) + *s++ = ch; + *s++ = 0; + return 1; +} +inline int read(const char *s) { return read((char *)s); } +inline int readline(char *s) { + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + *s++ = ch; + while (ch = gch(), !(ch == '\n' || ch == '\r') && ch != EOF) *s++ = ch; + *s++ = 0; + return 1; +} +inline int readline(const char *s) { return readline((char *)s); } +template +inline void write(T t) { + int stk[20], cnt = 0; + if (t == 0) { + wch('0'); + return; + } + if (t < 0) { + wch('-'); + t = -t; + } + while (t > 0) { + stk[cnt++] = t % 10; + t /= 10; + } + while (cnt) wch(stk[--cnt] + '0'); +} +inline void write(char t) { wch(t); } +inline void write(char *s) { + while (*s) wch(*s++); +} +inline void write(const char *s) { write((char *)s); } +#if __cplusplus >= 201103L +template +inline int read(T &t, Args &...args) { + return read(t) + read(args...); +} +template +inline void write(T t, Args... args) { + write(t); + write(args...); +} +#else +template +inline int read(A_t &a, B_t &b) { + return read(a) + read(b); +} +template +inline int read(A_t &a, B_t &b, C_t &c) { + return read(a) + read(b) + read(c); +} +template +inline int read(A_t &a, B_t &b, C_t &c, D_t &d) { + return read(a) + read(b) + read(c) + read(d); +} +template +inline void write(A_t a, B_t b) { + write(a); + write(b); +} +template +inline void write(A_t a, B_t b, C_t c) { + write(a); + write(b); + write(c); +} +template +inline void write(A_t a, B_t b, C_t c, D_t d) { + write(a); + write(b); + write(c); + write(d); +} +#endif +using namespace std; +typedef long long LL; +const int N = 100005, K = 25; +const LL inf = LONG_LONG_MAX; +int n, k; +LL a[N], f[K][N], t[N], lc = 1, rc, res; +void add(int x) { res += t[a[x]]++; } +void del(int x) { res -= --t[a[x]]; } +LL calc(int l, int r) { + while (lc > l) add(--lc); + while (rc < r) add(++rc); + while (lc < l) del(lc++); + while (rc > r) del(rc--); + return res; +} +void solve(int l, int r, int L, int R, LL k) { + if (l > r) return; + int mid = (l + r) >> 1, tmp = L; + LL mi = inf; + for (int i = min(mid - 1, R); i >= L; --i) + if (f[k - 1][i] + calc(i + 1, mid) < mi) + mi = f[k - 1][i] + calc(i + 1, mid), tmp = i; + f[k][mid] = mi; + solve(l, mid - 1, L, tmp, k); + solve(mid + 1, r, tmp, R, k); +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + read(n, k); + for (int i = 1; i <= n; ++i) read(a[i]); + solve(1, n, 0, 0, 1); + for (int i = 2; i <= k; ++i) solve(1, n, 0, n - 1, i); + write(f[k][n], '\n'); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2081.cpp b/ACMOJ-2081.cpp new file mode 100644 index 0000000..6347615 --- /dev/null +++ b/ACMOJ-2081.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +using namespace std; +typedef long long LL; +const LL kInf = 0x3f3f3f3f3f3f3f3fll; +const int kMaxN = 5010; +int n, k, h[kMaxN], tot_val, t[kMaxN]; +LL cnt[kMaxN], w[kMaxN][kMaxN], dp[kMaxN][2]; +int d[kMaxN][kMaxN]; +void Modify(int p, LL v) { + for (; p <= tot_val; p += p & (-p)) cnt[p] += v; +} +LL Query(int p) { + LL ret = 0; + for (; p > 0; p -= p & (-p)) ret += cnt[p]; + return ret; +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + scanf("%d%d", &n, &k); + // printf("%d %d\n",n,k); + for (int i = 1; i <= n; i++) { + scanf("%d", &h[i]); + t[i] = h[i]; + } + sort(t + 1, t + 1 + n); + int pos = 0; + t[0] = -kInf; + for (int i = 1; i <= n; i++) { + if (t[i] != t[pos]) t[++pos] = t[i]; + } + tot_val = pos; + for (int i = 1; i <= n; i++) h[i] = lower_bound(t + 1, t + 1 + n, h[i]) - t; + for (int i = 1; i <= n; i++) { + Modify(h[i], 1); + for (int j = i + 1; j <= n; j++) { + w[i][j] = w[i][j - 1] + j - i - Query(h[j]); + Modify(h[j], 1); + } + memset(cnt, 0, sizeof(cnt)); + } + memset(dp, 0x3f, sizeof(dp)); + dp[0][0] = 0; + for (int j = 1; j <= k; j++) { + d[n + 1][j] = n; + for (int i = n; i >= j; i--) { + for (int t = d[i][j - 1]; t <= d[i + 1][j]; t++) { + if (dp[t][(j - 1) & 1] + w[t + 1][i] < dp[i][j & 1]) { + dp[i][j & 1] = dp[t][(j - 1) & 1] + w[t + 1][i]; + d[i][j] = t; + } + } + } + } + printf("%lld\n", dp[n][k & 1]); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2090.cpp b/ACMOJ-2090.cpp new file mode 100644 index 0000000..c2eec02 --- /dev/null +++ b/ACMOJ-2090.cpp @@ -0,0 +1,22 @@ +#include "2090.hpp" + +#include + +signed main() { + sjtu::any_ptr a = sjtu::make_any_ptr(int(1)); + sjtu::any_ptr b = a; + + a.unwrap() = 2; + std::cerr << b.unwrap() << std::endl; // 2 + b = new std::string; + b.unwrap() = "Hello, world!"; + std::cerr << b.unwrap() << std::endl; // Hello, world! + + try { + a.unwrap() = "a"; + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; // bad cast + } + + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2090.hpp b/ACMOJ-2090.hpp new file mode 100644 index 0000000..708e491 --- /dev/null +++ b/ACMOJ-2090.hpp @@ -0,0 +1,162 @@ +#ifndef SRC_HPP +#define SRC_HPP + +#include +#include +// 以上是你所需要的头文件,如果你想使用其它头文件,请询问助教 +// 禁止使用 std::shared_ptr 与 std::any + +namespace sjtu { + +class any_ptr { + class Info_Base { + public: + int counter; + virtual ~Info_Base() {} + }; + template + class Info : public Info_Base { + public: + T *ptr; + Info(T *ptr) : ptr(ptr) {} + ~Info() override { delete ptr; } + }; + Info_Base *info = nullptr; + + public: + /** + * @brief 默认构造函数,行为应与创建空指针类似 + * + */ + any_ptr() {} + + /** + * @brief + * 拷贝构造函数,要求拷贝的层次为浅拷贝,即该对象与被拷贝对象的内容指向同一块内存 + * @note 若将指针作为参数传入,则指针的生命周期由该对象管理 + * @example + * any_ptr a = make_any_ptr(1); + * any_ptr b = a; + * a.unwrap = 2; + * std::cout << b << std::endl; // 2 + * @param other + */ + any_ptr(const any_ptr &other) { + info = other.info; + if (info) info->counter++; + } + template + any_ptr(T *ptr) { + info = new Info(ptr); + info->counter = 1; + } + + /** + * @brief + * 析构函数,注意若一块内存被多个对象共享,那么只有最后一个析构的对象需要释放内存 + * @example + * any_ptr a = make_any_ptr(1); + * { + * any_ptr b = a; + * } + * std::cout << a << std::endl; // valid + * @example + * int *p = new int(1); + * { + * any_ptr a = p; + * } + * std::cout << *p << std::endl; // invalid + * + */ + ~any_ptr() { + if (info) { + info->counter--; + if (info->counter == 0) { + delete info; + } + } + } + + /** + * @brief + * 拷贝赋值运算符,要求拷贝的层次为浅拷贝,即该对象与被拷贝对象的内容指向同一块内存 + * @note 应与指针拷贝赋值运算符的语义相近 + * @param other + * @return any_ptr& + */ + any_ptr &operator=(const any_ptr &other) { + if (info) { + info->counter--; + if (info->counter == 0) { + delete info; + } + } + info = other.info; + if (info) info->counter++; + return *this; + } + template + any_ptr &operator=(T *ptr) { + if (info) { + info->counter--; + if (info->counter == 0) { + delete info; + } + } + info = new Info(ptr); + info->counter = 1; + return *this; + } + + /** + * @brief 获取该对象指向的值的引用 + * @note 若该对象指向的值不是 T 类型,则抛出异常 std::bad_cast + * @example + * any_ptr a = make_any_ptr(1); + * std::cout << a.unwrap() << std::endl; // 1 + * @tparam T + * @return T& + */ + template + T &unwrap() { + Info *info_t = dynamic_cast *>(info); + if (info_t) + return *(info_t->ptr); + else + throw std::bad_cast(); + } + // 某一个 any_ptr 类对象可能为 const,请你补充 unwrap 函数 + template + const T &unwrap() const { + Info *info_t = dynamic_cast *>(info); + if (info_t) + return *(info_t->ptr); + else + throw std::bad_cast(); + } +}; + +/** + * @brief 由指定类型的值构造一个 any_ptr 对象 + * @example + * any_ptr a = make_any_ptr(1); + * any_ptr v = make_any_ptr>(1, 2, 3); + * any_ptr m = make_any_ptr>({{1, 2}, {3, 4}}); + * @tparam T + * @param t + * @return any_ptr + */ +template +any_ptr make_any_ptr(const T &t) { + return any_ptr(new T(t)); +} +// 某些 any_ptr 类对象可能由不定长参数或初始化列表构造,请你参照上方的 example +// 补充 make_any_ptr 函数,我们会有一个特殊的测试点测试你的程序是否完成要求 +template +any_ptr make_any_ptr(Args... args) { + return any_ptr(new T(std::forward(args)...)); +} + +} // namespace sjtu + +#endif \ No newline at end of file diff --git a/ACMOJ-2091.cpp b/ACMOJ-2091.cpp new file mode 100644 index 0000000..0e3a924 --- /dev/null +++ b/ACMOJ-2091.cpp @@ -0,0 +1,199 @@ +#include +#define unlikely(x) __builtin_expect(!!(x), 0) +struct char_reader { + FILE *f; + char *buf, *p1, *p2; + int size; + char_reader(FILE *fin, int bufsize = 1 << 16) { + f = fin; + size = bufsize; + p1 = p2 = 0; + buf = new char[size]; + } + ~char_reader() { delete[] buf; } + inline int operator()() { + return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, size, f), p1 == p2) + ? EOF + : *p1++; + } +}; +struct char_writer { + FILE *f; + char *buf, *p, *end; + int size; + char_writer(FILE *fout, int bufsize = 1 << 16) { + f = fout; + size = bufsize; + buf = new char[size]; + p = buf; + end = buf + bufsize; + } + ~char_writer() { + fwrite(buf, p - buf, 1, f); + delete[] buf; + } + inline char operator()(char ch) { + if (unlikely(end == p)) { + fwrite(buf, end - buf, 1, f); + p = buf; + } + return *p++ = ch; + } +}; +char_reader gch(stdin); +char_writer wch(stdout); +template +inline int read(T &t) { + bool f = false; + int ch; + while (ch = gch(), !((ch >= '0' && ch <= '9') || ch == '-')) { + if (ch == EOF) return 0; + } + t = 0; + if (ch == '-') f = true, ch = gch(); + t = ch ^ 48; + while (ch = gch(), ch >= '0' && ch <= '9') + t = (t << 3) + (t << 1) + (ch ^ 48); + if (f) t = -t; + return 1; +} +inline int read(char &c) { + c = 0; + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + c = ch; + return 1; +} +inline int read(char *s) { + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + *s++ = ch; + while (ch = gch(), + !(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t') && ch != EOF) + *s++ = ch; + *s++ = 0; + return 1; +} +inline int read(const char *s) { return read((char *)s); } +inline int readline(char *s) { + int ch; + while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) { + if (ch == EOF) return 0; + } + *s++ = ch; + while (ch = gch(), !(ch == '\n' || ch == '\r') && ch != EOF) *s++ = ch; + *s++ = 0; + return 1; +} +inline int readline(const char *s) { return readline((char *)s); } +template +inline void write(T t) { + int stk[20], cnt = 0; + if (t == 0) { + wch('0'); + return; + } + if (t < 0) { + wch('-'); + t = -t; + } + while (t > 0) { + stk[cnt++] = t % 10; + t /= 10; + } + while (cnt) wch(stk[--cnt] + '0'); +} +inline void write(char t) { wch(t); } +inline void write(char *s) { + while (*s) wch(*s++); +} +inline void write(const char *s) { write((char *)s); } +#if __cplusplus >= 201103L +template +inline int read(T &t, Args &...args) { + return read(t) + read(args...); +} +template +inline void write(T t, Args... args) { + write(t); + write(args...); +} +#else +template +inline int read(A_t &a, B_t &b) { + return read(a) + read(b); +} +template +inline int read(A_t &a, B_t &b, C_t &c) { + return read(a) + read(b) + read(c); +} +template +inline int read(A_t &a, B_t &b, C_t &c, D_t &d) { + return read(a) + read(b) + read(c) + read(d); +} +template +inline void write(A_t a, B_t b) { + write(a); + write(b); +} +template +inline void write(A_t a, B_t b, C_t c) { + write(a); + write(b); + write(c); +} +template +inline void write(A_t a, B_t b, C_t c, D_t d) { + write(a); + write(b); + write(c); + write(d); +} +#endif +#include +using namespace std; + +typedef long long LL; +const int kMaxN = 1000000 + 10; +const int kMaxS = 1000 + 10; +int n, tot[kMaxS]; +LL s[kMaxN], c[kMaxN], f[kMaxN]; +vector stk[kMaxS]; + +inline LL X(int i) { return c[i]; } +inline LL Y(int i) { return f[i - 1] + s[i] * c[i] * c[i] - 2 * s[i] * c[i]; } +inline double Slope(int i, int j) { + return (Y(i) - Y(j)) / double(X(i) - X(j)); +} +inline LL Calc(int i, int j) { + return f[j - 1] + s[i] * (c[i] - c[j] + 1) * (c[i] - c[j] + 1); +} + +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + read(n); + for (int i = 1; i <= n; ++i) { + read(s[i]); + c[i] = ++tot[s[i]]; + } + for (int i = 1; i <= n; ++i) { + int t = s[i]; + while (stk[t].size() >= 2 && + Slope(stk[t][stk[t].size() - 2], i) >= + Slope(stk[t][stk[t].size() - 2], stk[t][stk[t].size() - 1])) + stk[t].pop_back(); + stk[t].push_back(i); + while (stk[t].size() >= 2 && Calc(i, stk[t][stk[t].size() - 1]) <= + Calc(i, stk[t][stk[t].size() - 2])) + stk[t].pop_back(); + f[i] = Calc(i, stk[t][stk[t].size() - 1]); + } + write(f[n], '\n'); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2095.cpp b/ACMOJ-2095.cpp new file mode 100644 index 0000000..37baac8 --- /dev/null +++ b/ACMOJ-2095.cpp @@ -0,0 +1,51 @@ +#include "ACMOJ-2095.hpp" + +#include + +struct koishi { + int id; + koishi() = default; + koishi(int id) : id(id) {} +}; + +std::ostream &operator<<(std::ostream &os, const koishi &k) { + return os << "Komeiji Koishi " << k.id; +} + +void test0() { + using sjtu::unique_ptr; + unique_ptr ptr1(new int(114514)); + + // 移交所有权 + unique_ptr ptr2(std::move(ptr1)); + + // 释放所有权 + int *tmp = ptr2.release(); + delete tmp; +} + +void test1() { + using sjtu::unique_ptr; + unique_ptr ptr1 = sjtu::make_unique(koishi(1)); + + // 这个行为可能是未定义的,但是我们要求其应该可以正常工作 + ptr1 = std::move(ptr1); + + // 成员访问 + ptr1->id = 514; + + // 解引用 + std::cout << *ptr1 << std::endl; + + // 重置,现在 ptr1 应该为空 + ptr1.reset(); + if (!ptr1.get()) { + std::cout << "ptr1 is empty!" << '\n'; + } +} + +signed main() { + test0(); + test1(); + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2095.hpp b/ACMOJ-2095.hpp new file mode 100644 index 0000000..3170f24 --- /dev/null +++ b/ACMOJ-2095.hpp @@ -0,0 +1,101 @@ +#pragma once +#include +#include +// 你不可以使用其他任何头文件 + +namespace sjtu { + +/** + * @brief 一个可以在离开作用域之后自动归还内存的指针。 + * unique_ptr <_Tp> 行为应该和普通指针 _Tp * 几乎一致。 + * @tparam _Tp 模板参数,指针指向的类型。 + */ +template +class unique_ptr { + private: + // 你可以自由地增加成员变量和成员函数 + _Tp *ptr=nullptr; + + public: + // 构造一个空的指针 (nullptr) + unique_ptr() : ptr(nullptr){} + + // 同一个指针不能被多个 unique_ptr 指向 + unique_ptr(const unique_ptr &) = delete; + + // 移动构造函数。移交所有权。 + // 注意移交后要把 other 置空。 + unique_ptr(unique_ptr &&other) { + ptr = other.ptr; + other.ptr = nullptr; + } + + // 析构函数。释放指针指向的内存。 + // 需要注意,delete nullptr 是安全的。 + ~unique_ptr() { delete ptr; } + + // 同一个指针不能被多个 unique_ptr 指向 + unique_ptr &operator=(const unique_ptr &) = delete; + + // 移动赋值运算符。移交所有权。 + // 注意移交后要把 other 置空。 + unique_ptr &operator=(unique_ptr &&other) { + if (this == &other) return *this; + delete ptr; + ptr = other.ptr; + other.ptr = nullptr; + return *this; + } + + // 接管一个普通 _Tp 类型的指针的所有权 + explicit unique_ptr(_Tp *address) : ptr(address) {} + + // 重置为空指针。同时释放指针指向的内存。 + void reset() { + delete ptr; + ptr = nullptr; + } + + // 转移所有权,返回指针指向的对象的地址 + // 同时,自己要置空。 + _Tp *release() { + _Tp *ptr_tmp = ptr; + ptr = nullptr; + return ptr_tmp; + } + + // 返回指针指向的对象的地址 + // 所有权不转移。 + _Tp *get() const noexcept { return ptr; } + + // 重载 * 运算符(解引用),返回指针指向的对象的引用 + _Tp &operator*() noexcept { return *ptr; } + + // 重载 -> 运算符(成员访问),返回指针指向的对象的地址 + _Tp *operator->() noexcept { return ptr; } +}; + +// 对于一个 unique_ptr,你最多只能存一个指针 +static_assert(sizeof(unique_ptr) <= sizeof(void *)); + +// // 创建一个 unique_ptr,指向一个用 new 分配的 _Tp 对象 +// template +// unique_ptr <_Tp> make_unique(const _Tp &val) +// { +// return std::move(unique_ptr<_Tp>(new _Tp(val))); +// } + +// Bonus: (不作为考察内容) +// (如果写了,请删除上面的这个 make_unique) +// (否则,请删除下面的这个 make_unique) +// 可变长参数列表 + 万能引用 +// 创建一个 unique_ptr,指向一个用 new 分配的 _Tp 对象 +// 参数列表长度可变,且有左值引用和右值引用两种版本 +// 当传入左值 T &, Args 类型被推导为 T & +// 当传入右值 T &&,Args 类型被推导为 T +// 你需要了解如何用 std::forward 实现完美转发 +template +unique_ptr<_Tp> make_unique(Args &&...args) { + return std::move(unique_ptr<_Tp>(new _Tp(std::forward(args)...))); +} +} // namespace sjtu \ No newline at end of file diff --git a/ACMOJ-2096.cpp b/ACMOJ-2096.cpp new file mode 100644 index 0000000..45895a2 --- /dev/null +++ b/ACMOJ-2096.cpp @@ -0,0 +1,32 @@ +#include +#include "ACMOJ-2096.hpp" + +#include + +signed main() { + using koishi::any; + any x; + x = 1919810; + std::cout << x.cast () << std::endl; + x = 114.514; + + try { + std::cout << x.cast () << std::endl; + } catch (const std::exception &e) { + std::cout << e.what() << std::endl; + } + + auto ptr = x.try_cast (); + if (ptr) std::cout << "Double value: " << *ptr << std::endl; + // if C++ 17 or later, try this: + // if (auto ptr = x.try_cast ()) std::cout << "Double value: " << *ptr << std::endl; + + any y {x}; + std::cout << y.cast () << std::endl; + + any z {std::move(x)}; + if (x.is_empty()) std::cout << "x is empty" << std::endl; + + std::cout << z.cast () << std::endl; + return 0; +} \ No newline at end of file diff --git a/ACMOJ-2096.hpp b/ACMOJ-2096.hpp new file mode 100644 index 0000000..8141e8b --- /dev/null +++ b/ACMOJ-2096.hpp @@ -0,0 +1,138 @@ +#pragma once +#include +#include +#include +// 你不可以使用任何其他的头文件 + +namespace koishi { + +/** + * @brief 一个可以存储任意类型的类 (确信)。 + * 其要么存储了某个类型的值,要么为空(不存储任何值)。 + */ +class any { + private: + // 你不可以额外添加任何成员变量。 + // base 类的实现在 any 类的尾部。 + // 你需要通过观察 base 和 storage 类的实现来完成 any 类的实现。 + + // 以下是 base 类和 storage 类的实现。 + // 你可以思考一下为什么要这么设计。 + // 事实上 any 类的设计并不唯一,标准库也并不是这么写的 + // 标准库使用函数指针那种写法,我觉得还是这种写法比较好理解些。 + + struct base { + virtual ~base() = default; + virtual base *clone() const = 0; + }; + + template + struct storage : base { + T value; // 真实的数据存储在这里哦 + + // 完美转发,接受任意类型的参数 + // 现在 storage 有 T 所有的构造函数了 + template + storage(Args &&args) : value(std::forward(args)) {} + + // 拷贝一份自己,返回基类的指针。 + base *clone() const override { return new storage(value); } + }; + base *ptr = nullptr; // 指向基类的指针 + + public: + // 默认构造函数,创建一个空的 any 对象。 + any() = default; + + // 你同样可以使用 nullptr 来创建一个空的 any 对象。 + any(std::nullptr_t) : any() {} + + // 销毁当前对象。 + // 重申: delete nullptr 是安全的。 + ~any() { delete ptr; } + + // 拷贝构造函数,创建一个和 other 一样的 any 对象。 + // 可能要用到 clone() 函数 + any(const any &other) { + if (other.ptr) ptr = other.ptr->clone(); + } + + // 移动构造函数,创建一个和 other 一样的 any 对象。 + // 你只需要移走 other 的数据,使得 other 为空即可。 + // 你不应该用到 clone() 函数 + any(any &&other) { + ptr = other.ptr; + other.ptr = nullptr; + } + + // 创建一个存储了某个类型的值的 any 对象。 + // 你不用管模板的第二个参数。那是用来约束 T ,保证 T 不是 any 类型的。 + template , any>>> + any(const T &val) { + ptr = new storage(val); + } + + // 拷贝赋值运算符,要求类似拷贝构造函数。 + any &operator=(const any &other) { + if (ptr) delete ptr; + ptr = nullptr; + if (other.ptr) ptr = other.ptr->clone(); + return *this; + } + + // 移动赋值运算符,要求类似移动构造函数。 + any &operator=(any &&other) { + if (ptr) delete ptr; + ptr = other.ptr; + other.ptr = nullptr; + return *this; + } + + // 强行把当前对象转换成 T 类型。 + // 如果当前存储的不是 T 类型的值,那么抛出异常 std::bad_cast + template + T &cast() { + storage *new_ptr = dynamic_cast *>(ptr); + if (new_ptr != nullptr) + return new_ptr->value; + else + throw std::bad_cast(); + } + + // 差不多,但是是 const 版本的。 + template + const T &cast() const { + storage *new_ptr = dynamic_cast *>(ptr); + if (new_ptr != nullptr) + return new_ptr->value; + else + throw std::bad_cast(); + } + + // 尝试把当前对象转换成 T 类型。 + // 如果当前存储的不是 T 类型的值,那么返回 nullptr + template + T *try_cast() { + storage *new_ptr = dynamic_cast *>(ptr); + if (new_ptr != nullptr) + return &new_ptr->value; + else + return nullptr; + } + + // 差不多,但是是 const 版本的。 + template + const T *try_cast() const { + storage *new_ptr = dynamic_cast *>(ptr); + if (new_ptr != nullptr) + return &new_ptr->value; + else + return nullptr; + } + + // 判断当前对象是否为空。 + bool is_empty() const { return ptr == nullptr; } +}; + +} /* namespace koishi */ \ No newline at end of file diff --git a/ACMOJ1328.hpp b/ACMOJ1328.hpp new file mode 100644 index 0000000..874e512 --- /dev/null +++ b/ACMOJ1328.hpp @@ -0,0 +1,11 @@ +#include +void debugPrint() { std::cout << std::endl; } +template +void debugPrint(T x) { + std::cout << x << std::endl; +} +template +void debugPrint(T x, Args... args) { + std::cout << x << " "; + debugPrint(args...); +} \ No newline at end of file diff --git a/Luogu-P1742.cpp b/Luogu-P1742.cpp new file mode 100644 index 0000000..ab72f9b --- /dev/null +++ b/Luogu-P1742.cpp @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +const double EPS = 1e-10; +struct point { + double x, y; + inline point operator+(point rhs) const { + return (point){x + rhs.x, y + rhs.y}; + } + inline point operator-(point rhs) const { + return (point){x - rhs.x, y - rhs.y}; + } + inline point operator*(double rhs) const { return (point){x * rhs, y * rhs}; } + inline double len() const { return sqrt(x * x + y * y); } +}; +inline int sgn(double x) { + if (x < -EPS) return -1; + if (x > EPS) return 1; + return 0; +} +inline double det(point x, point y) { return x.x * y.y - x.y * y.x; } +inline double dot(point x, point y) { return x.x * y.x + x.y * y.y; } +inline double dis(point x, point y) { return (x - y).len(); } +struct circle { + point c; + double r; +}; +inline bool in_circle(point p, circle c) { + return sgn(c.r - (c.c - p).len()) >= 0; +} +inline circle make_circle(point x, point y) { + return (circle){(x + y) * 0.5, (x - y).len() * 0.5}; +} +inline circle make_circle(point x, point y, point z) { + point p = y - x, q = z - x, s = (point){dot(p, p) * 0.5, dot(q, q) * 0.5}; + double d = 1.0 / det(p, q); + p = (point){det(s, (point){p.y, q.y}), det((point){p.x, q.x}, s)} * d; + return (circle){x + p, p.len()}; +} +inline circle get_circle(point x, point y, point z) { + if (sgn(det(y - x, z - x)) == 0) { + if ((x - y).len() >= (x - z).len()) { + if ((x - y).len() >= (y - z).len()) + return make_circle(x, y); + else + return make_circle(y, z); + } else { + if ((x - z).len() >= (y - z).len()) + return make_circle(x, z); + else + return make_circle(y, z); + } + } else + return make_circle(x, y, z); +} +using namespace std; +const int maxn = 1e5 + 10; +mt19937 rnd(random_device{}()); +inline int rand_less(int n) { return rnd() % n; } +int n; +point pnt[maxn]; +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + scanf("%d", &n); + for (int i = 1; i <= n; i++) scanf("%lf%lf", &pnt[i].x, &pnt[i].y); + if (n == 2) { + printf("%.10lf\n", dis(pnt[1], pnt[2]) / 2); + printf("%.10lf %.10lf\n",((pnt[1]+pnt[2])*0.5).x,((pnt[1]+pnt[2])*0.5).y); + return 0; + } + random_shuffle(pnt + 1, pnt + 1 + n, rand_less); + circle cc = {pnt[1], 0}; + // 注意:此处不要自作聪明地初始化,必须保证一定是真正的最小圆覆盖 + for (int i = 2; i <= n; i++) { + if (in_circle(pnt[i], cc)) continue; + cc = make_circle(pnt[i], pnt[1]); + for (int j = 2; j <= i - 1; j++) { + if (in_circle(pnt[j], cc)) continue; + cc = make_circle(pnt[j], pnt[i]); + for (int k = 1; k <= j - 1; k++) { + if (in_circle(pnt[k], cc)) continue; + cc = get_circle(pnt[k], pnt[j], pnt[i]); + } + } + } + printf("%.10lf\n", cc.r); + printf("%.10lf %.10lf\n",cc.c.x,cc.c.y); + return 0; +} \ No newline at end of file diff --git a/Luogu-P2346.cpp b/Luogu-P2346.cpp new file mode 100644 index 0000000..ad328a0 --- /dev/null +++ b/Luogu-P2346.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +using namespace std; +typedef unsigned int UI; +typedef long long LL; +unordered_map dist; +inline UI mp2id(char mp[4][6]) { + UI pid = 0; + UI res = 0; + UI blank_pos = 0; + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) { + res <<= 1; + if (mp[i][j] == 'B') + res |= 1; + else if (mp[i][j] == 'W') + res = res; + else + blank_pos = blank_pos * 16 + pid; + pid++; + } + return (blank_pos << 16) + res; +} +inline void id2mp(UI status, char mp[4][6], int &bp1, int &bp2) { + UI blank_pos = (status >> 16) & 255; + const static int rid[16] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3}; + const static int cid[16] = {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3}; + for (int i = 0; i < 16; i++) + if (status & (1 << (15 - i))) + mp[rid[i]][cid[i]] = 'B'; + else + mp[rid[i]][cid[i]] = 'W'; + mp[rid[blank_pos & 15]][cid[blank_pos & 15]] = 'O'; + mp[rid[(blank_pos >> 4) & 15]][cid[(blank_pos >> 4) & 15]] = 'O'; + bp1 = blank_pos & 15; + bp2 = (blank_pos >> 4) & 15; +} +inline bool ok(char mp[4][6]) { + for (int i = 0; i < 4; i++) { + char c = mp[i][0]; + for (int j = 1; j < 4; j++) + if (mp[i][j] != c) goto nxt1; + return true; + nxt1:; + } + for (int j = 0; j < 4; j++) { + char c = mp[0][j]; + for (int i = 1; i < 4; i++) + if (mp[i][j] != c) goto nxt2; + return true; + nxt2:; + } + if (mp[0][0] == mp[1][1] && mp[1][1] == mp[2][2] && mp[2][2] == mp[3][3]) + return true; + if (mp[0][3] == mp[1][2] && mp[1][2] == mp[2][1] && mp[2][1] == mp[3][0]) + return true; + return false; +} +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + const static int rid[16] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3}; + const static int cid[16] = {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3}; + char mp[4][6], mpv[4][6]; + for (int i = 0; i < 4; i++) scanf("%s", mp[i]); + UI bg = mp2id(mp); + if (ok(mp)) { + puts("0"); + return 0; + } + dist[bg | (1 << 24)] = 0; + dist[bg | (0 << 24)] = 0; + queue Q; + Q.push(bg | (1 << 24)); + Q.push(bg | (0 << 24)); + char lch[3] = "BW"; + while (Q.size()) { + UI u = Q.front(); + UI ls = u >> 24; + const int d = dist[u]; + Q.pop(); + int bp[2]; + id2mp(u, mp, bp[0], bp[1]); + for (int p = 0; p < 2; p++) { + const int blank_pos = bp[p]; + const int br = rid[blank_pos], bc = cid[blank_pos]; + static const int dr[4] = {0, -1, 0, 1}; + static const int dc[4] = {-1, 0, 1, 0}; + for (int i = 0; i < 4; i++) { + int nr = br + dr[i], nc = bc + dc[i]; + if (nr < 0 || nr >= 4 || nc < 0 || nc >= 4) continue; + if (mp[nr][nc] == 'O') continue; + if (mp[nr][nc] != lch[ls]) continue; + memcpy(mpv, mp, sizeof(mp)); + swap(mpv[br][bc], mpv[nr][nc]); + UI v = mp2id(mpv)|((ls^1)<<24); + if (ok(mpv)) { + printf("%d\n", d + 1); + return 0; + } + if (dist.find(v) != dist.end()) continue; + dist[v] = d + 1; + Q.push(v); + } + } + } + return 0; +} \ No newline at end of file diff --git a/Luogu-P2533.cpp b/Luogu-P2533.cpp new file mode 100644 index 0000000..1b3b8e7 --- /dev/null +++ b/Luogu-P2533.cpp @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +const double EPS = 1e-7; +struct point { + double x, y; + inline point operator+(point rhs) const { + return (point){x + rhs.x, y + rhs.y}; + } + inline point operator-(point rhs) const { + return (point){x - rhs.x, y - rhs.y}; + } + inline point operator*(double rhs) const { return (point){x * rhs, y * rhs}; } + inline double len() const { return sqrt(x * x + y * y); } +}; +inline int sgn(double x) { + if (x < -EPS) return -1; + if (x > EPS) return 1; + return 0; +} +inline double det(point x, point y) { return x.x * y.y - x.y * y.x; } +inline double dot(point x, point y) { return x.x * y.x + x.y * y.y; } +inline double dis(point x, point y) { return (x - y).len(); } +struct circle { + point c; + double r; +}; +inline bool in_circle(point p, circle c) { + return sgn(c.r - (c.c - p).len()) >= 0; +} +inline circle make_circle(point x, point y) { + return (circle){(x + y) * 0.5, (x - y).len() * 0.5}; +} +inline circle make_circle(point x, point y, point z) { + point p = y - x, q = z - x, s = (point){dot(p, p) * 0.5, dot(q, q) * 0.5}; + double d = 1.0 / det(p, q); + p = (point){det(s, (point){p.y, q.y}), det((point){p.x, q.x}, s)} * d; + return (circle){x + p, p.len()}; +} +inline circle get_circle(point x, point y, point z) { + if (sgn(det(y - x, z - x)) == 0) { + if ((x - y).len() >= (x - z).len()) { + if ((x - y).len() >= (y - z).len()) + return make_circle(x, y); + else + return make_circle(y, z); + } else { + if ((x - z).len() >= (y - z).len()) + return make_circle(x, z); + else + return make_circle(y, z); + } + } else + return make_circle(x, y, z); +} +using namespace std; +const int maxn = 1e6 + 10; +mt19937 rnd(random_device{}()); +inline int rand_less(int n) { return rnd() % n; } +int n; +point pnt[maxn]; +int main() { +#ifdef local + freopen("pro.in", "r", stdin); +#endif + scanf("%d", &n); + for (int i = 1; i <= n; i++) scanf("%lf%lf", &pnt[i].x, &pnt[i].y); + if (n == 2) { + printf("%.2lf %.2lf %.2lf\n", ((pnt[1] + pnt[2]) * 0.5).x, + ((pnt[1] + pnt[2]) * 0.5).x, dis(pnt[1], pnt[2]) / 2); + return 0; + } + random_shuffle(pnt + 1, pnt + 1 + n, rand_less); + circle cc = {pnt[1], 0}; + // 注意:此处不要自作聪明地初始化,必须保证一定是真正的最小圆覆盖 + for (int i = 2; i <= n; i++) { + if (in_circle(pnt[i], cc)) continue; + cc = make_circle(pnt[i], pnt[1]); + for (int j = 2; j <= i - 1; j++) { + if (in_circle(pnt[j], cc)) continue; + cc = make_circle(pnt[j], pnt[i]); + for (int k = 1; k <= j - 1; k++) { + if (in_circle(pnt[k], cc)) continue; + cc = get_circle(pnt[k], pnt[j], pnt[i]); + } + } + } + printf("%.2lf %.2lf %.2lf\n", cc.c.x, cc.c.y, cc.r); + return 0; +} \ No newline at end of file