Init
This commit is contained in:
136
ACMOJ-1018.cpp
Normal file
136
ACMOJ-1018.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
#include<cassert>
|
||||
#include<vector>
|
||||
#include<random>
|
||||
// #include<map>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
typedef pair<int,LL> SufType;
|
||||
const int maxn=1005;
|
||||
int N,K,a[maxn];
|
||||
bool used[maxn];
|
||||
vector<int> 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<<TotalNotFixed)-1)^st,K-CurrentPair)];
|
||||
return;
|
||||
}
|
||||
int valid=((1<<TotalNotFixed)-1)^st;
|
||||
for(;valid;valid-=valid&(-valid))
|
||||
{
|
||||
int i=hsh[valid&(-valid)];
|
||||
if((st&(1<<i))==0
|
||||
&&CurrentPair+InnerPair[st][i]+OuterPair[dep][i]<=K
|
||||
&&!(K>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<<i));
|
||||
}
|
||||
}
|
||||
}
|
||||
int main()
|
||||
{
|
||||
#ifdef local
|
||||
freopen("pro.in","r",stdin);
|
||||
#endif
|
||||
scanf("%d%d",&N,&K);
|
||||
for(int i=1;i<=N;i++)
|
||||
{
|
||||
scanf("%d",&a[i]);
|
||||
used[a[i]]=true;
|
||||
if(a[i]==0) position.push_back(i);
|
||||
assert(0<=a[i]&&a[i]<=N);
|
||||
}
|
||||
LL AlreadyHave=0;
|
||||
for(int i=1;i<=N;i++)
|
||||
for(int j=i+1;j<=N;j++)
|
||||
if(a[i]!=0&&a[j]!=0&&a[i]>a[j])
|
||||
AlreadyHave++;
|
||||
for(int i=1;i<=N;i++)
|
||||
if(!used[i])
|
||||
number.push_back(i);
|
||||
TotalNotFixed=position.size();
|
||||
for(int i=0;i<TotalNotFixed;i++)
|
||||
{
|
||||
const int pos=position[i];
|
||||
for(int j=0;j<TotalNotFixed;j++)
|
||||
{
|
||||
const int num=number[j];
|
||||
for(int k=1;k<=N;k++)
|
||||
if((a[k]!=0&&k<pos&&a[k]>num)||(a[k]!=0&&k>pos&&a[k]<num))
|
||||
OuterPair[i][j]++;
|
||||
}
|
||||
}
|
||||
for(int st=0;st<(1<<TotalNotFixed);st++)
|
||||
for(int p=0;p<TotalNotFixed;p++)
|
||||
for(int i=0;i<TotalNotFixed;i++)
|
||||
if((st&(1<<i))&&number[i]>number[p])
|
||||
InnerPair[st][p]++;
|
||||
if(K>AlreadyHave+TotalNotFixed*(TotalNotFixed-1)/2+TotalNotFixed*(N-TotalNotFixed))
|
||||
{
|
||||
puts("0");
|
||||
return 0;
|
||||
}
|
||||
for(int i=0;i<TotalNotFixed;i++) hsh[1<<i]=i;
|
||||
SufLength=(TotalNotFixed+1)/2;
|
||||
PreLength=TotalNotFixed-SufLength;
|
||||
const int FullStatus=(1<<TotalNotFixed)-1;
|
||||
for(int st=0;st<(1<<TotalNotFixed);st++)
|
||||
{
|
||||
if(__builtin_popcount(st)==SufLength)
|
||||
{
|
||||
const int PreStatus=FullStatus^st;
|
||||
int p[10],pcnt=0;
|
||||
for(int i=0;i<TotalNotFixed;i++)
|
||||
if(st&(1<<i))
|
||||
p[pcnt++]=i;
|
||||
assert(pcnt==SufLength);
|
||||
do
|
||||
{
|
||||
LL tmp=0,AlreadyProced=0;
|
||||
for(int i=0;i<SufLength;i++)
|
||||
{
|
||||
tmp+=OuterPair[TotalNotFixed-SufLength+i][p[i]];
|
||||
tmp+=InnerPair[PreStatus][p[i]];
|
||||
tmp+=InnerPair[AlreadyProced][p[i]];
|
||||
AlreadyProced|=1<<p[i];
|
||||
}
|
||||
SufData[SufType(st,tmp)]++;
|
||||
} while (next_permutation(p,p+SufLength));
|
||||
}
|
||||
}
|
||||
dfs(0,AlreadyHave,0);
|
||||
printf("%lld\n",Answer);
|
||||
return 0;
|
||||
}
|
16
ACMOJ-1040.cpp
Normal file
16
ACMOJ-1040.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include <iostream>
|
||||
#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;
|
||||
}
|
37
ACMOJ-1040.hpp
Normal file
37
ACMOJ-1040.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#ifndef __PROTECTOR_ACMOJ_1040__
|
||||
#define __PROTECTOR_ACMOJ_1040__
|
||||
#include <functional>
|
||||
#include <random>
|
||||
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
|
13
ACMOJ-1048.cpp
Normal file
13
ACMOJ-1048.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "ACMOJ-1048.hpp"
|
||||
#include<iostream>
|
||||
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;
|
||||
}
|
13
ACMOJ-1048.hpp
Normal file
13
ACMOJ-1048.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include <functional>
|
||||
#include <stack>
|
||||
class Defer {
|
||||
std::stack<std::function<void()>> stk;
|
||||
|
||||
public:
|
||||
~Defer() {
|
||||
while (!stk.empty()) stk.top()(), stk.pop();
|
||||
}
|
||||
Defer() = default;
|
||||
Defer(std::function<void()> f) { stk.push(f); }
|
||||
void operator()(std::function<void()> f) { stk.push(f); }
|
||||
};
|
48
ACMOJ-1444.cpp
Normal file
48
ACMOJ-1444.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "ACMOJ-1444.hpp"
|
||||
#include <bits/stdc++.h>
|
||||
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;
|
||||
}
|
72
ACMOJ-1444.hpp
Normal file
72
ACMOJ-1444.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
#ifndef EVIL_HPP
|
||||
#define EVIL_HPP
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
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
|
12
ACMOJ-1447.cpp
Normal file
12
ACMOJ-1447.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include <iostream>
|
||||
#include "ACMOJ-1447.hpp"
|
||||
void print(int argc,char** argv){
|
||||
for(int i=0;i<argc;++i)
|
||||
std::cout<<i<<": "<<argv[i]<<std::endl;
|
||||
}
|
||||
int main(){
|
||||
final::shell shell;
|
||||
shell.run(0,"echo 'Hello,world'",print);
|
||||
shell.subprocessExit(0,0);
|
||||
return 0;
|
||||
}
|
89
ACMOJ-1447.hpp
Normal file
89
ACMOJ-1447.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
// 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<char *> 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<int, arguments> running_list;
|
||||
|
||||
public:
|
||||
shell() = default;
|
||||
|
||||
void run(int pid, const string &cmd,
|
||||
const function<void(int, char **)> &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<int> getRunningList() const {
|
||||
vector<int> rt;
|
||||
for (auto &pair : running_list) rt.push_back(pair.first);
|
||||
return rt;
|
||||
}
|
||||
};
|
||||
} // namespace final
|
14
ACMOJ-1663.cpp
Normal file
14
ACMOJ-1663.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
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<n;i++) { scanf("%d",&a); res^=a; }
|
||||
printf("%d\n",res);
|
||||
return 0;
|
||||
}
|
60
ACMOJ-1665.cpp
Normal file
60
ACMOJ-1665.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
#include<algorithm>
|
||||
#include<cstring>
|
||||
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<k;i++)
|
||||
{
|
||||
int u,v; scanf("%d%d",&u,&v);
|
||||
fa[ff(u)]=ff(v);
|
||||
}
|
||||
for(int i=1;i<=n;i++)
|
||||
cnt[ff(i)]++;
|
||||
for(int i=1;i<=n;i++)
|
||||
if(cnt[i])
|
||||
a[acnt++]=cnt[i];
|
||||
sort(a,a+acnt);
|
||||
vis[0]=1;
|
||||
for(int i=0;i<acnt;i++)
|
||||
for(int j=n;j>=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;
|
||||
}
|
61
ACMOJ-1669.cpp
Normal file
61
ACMOJ-1669.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
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]<position[p-1]-position[k])
|
||||
p--;
|
||||
dp[i][j]=min(dp[i][j],
|
||||
dp[k][j-1]
|
||||
-(n-i+1)*(position[i]-position[k])
|
||||
-pre[k][i-1]+pre[k][p-1]+suf[i][p]
|
||||
);
|
||||
}
|
||||
}
|
||||
int res=inf;
|
||||
for(int i=1;i<=n;i++) res=min(res,dp[i][m]);
|
||||
printf("%d\n",res);
|
||||
return 0;
|
||||
}
|
71
ACMOJ-1685.cpp
Normal file
71
ACMOJ-1685.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
#include<vector>
|
||||
#include<set>
|
||||
#include<map>
|
||||
#include<cassert>
|
||||
#include<cmath>
|
||||
#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]<QR[q2]:QL[q1]<QL[q2];
|
||||
}
|
||||
void Add(int x,int y)
|
||||
{
|
||||
x++;
|
||||
for(;x<=N+1;x+=lowbit(x)) BST[x]+=y;
|
||||
}
|
||||
int query(int x)
|
||||
{
|
||||
x++;
|
||||
int res=0;
|
||||
for(;x;x-=lowbit(x)) res+=BST[x];
|
||||
return res;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
#ifdef local
|
||||
freopen("pro.in","r",stdin);
|
||||
#endif
|
||||
scanf("%d%d",&N,&Q);
|
||||
set<int> st;
|
||||
for(int i=1;i<=N;i++)
|
||||
{
|
||||
scanf("%d",&a[i]);
|
||||
st.insert(a[i]);
|
||||
}
|
||||
map<int,int> 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;
|
||||
}
|
238
ACMOJ-1686.cpp
Normal file
238
ACMOJ-1686.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
#include<cassert>
|
||||
#include<cstdio>
|
||||
#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<typename T> 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<typename T> 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<typename T,typename... Args> inline int read(T& t,Args&... args) { return read(t)+read(args...); }
|
||||
template<typename T,typename... Args> inline void write(T t,Args... args) { write(t); write(args...); }
|
||||
#else
|
||||
template<typename A_t,typename B_t> inline int read(A_t &a,B_t &b) { return read(a)+read(b); }
|
||||
template<typename A_t,typename B_t,typename C_t> inline int read(A_t &a,B_t &b,C_t &c) { return read(a)+read(b)+read(c); }
|
||||
template<typename A_t,typename B_t,typename C_t,typename D_t> 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<typename A_t,typename B_t> inline void write(A_t a,B_t b) { write(a); write(b); }
|
||||
template<typename A_t,typename B_t,typename C_t> inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); }
|
||||
template<typename A_t,typename B_t,typename C_t,typename D_t> 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<m;i++)
|
||||
{
|
||||
int l,r; read(l,r);
|
||||
SgT.InverseRange(l,r);
|
||||
write(Solve(),'\n');
|
||||
}
|
||||
return 0;
|
||||
}
|
63
ACMOJ-1687.cpp
Normal file
63
ACMOJ-1687.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#include<iostream>
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
#include<cassert>
|
||||
#include<string>
|
||||
#include<cstdio>
|
||||
#include<queue>
|
||||
#include<map>
|
||||
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(;p<maxv;p+=p&(-p))
|
||||
mem[p]+=v;
|
||||
}
|
||||
inline LL query(int p)
|
||||
{
|
||||
LL res=0;
|
||||
for(;p>0;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<maxv;v++,L+=a[i])
|
||||
{
|
||||
int R=min(maxv-1,L+a[i]-1);
|
||||
delta-=LL(a[i])*v*(num_cnt.query(R)-num_cnt.query(L-1));
|
||||
}
|
||||
delta-=pre_influence.query(a[i]);
|
||||
res+=delta;
|
||||
printf("%lld ",res);
|
||||
num_cnt.add(a[i],1);
|
||||
value_tot.add(a[i],a[i]);
|
||||
for(int L=a[i];L<maxv;L+=a[i])
|
||||
pre_influence.add(L,a[i]);
|
||||
// puts("\n_______\n");
|
||||
}
|
||||
puts("");
|
||||
return 0;
|
||||
}
|
73
ACMOJ-1706.cpp
Normal file
73
ACMOJ-1706.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
#include<cassert>
|
||||
#include<string>
|
||||
#include<queue>
|
||||
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<A.UDist;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
#ifdef local
|
||||
freopen("pro.in","r",stdin);
|
||||
// freopen("pro.out","w",stdout);
|
||||
#endif
|
||||
scanf("%d%d%d%d%d%d",&n,&m,&s,&t,&g,&q);
|
||||
for(int i=1;i<=n;i++)
|
||||
{
|
||||
scanf("%d%d",&h[i],&l[i]);
|
||||
TMax[i]=(l[i]-h[i])/q;
|
||||
}
|
||||
for(int i=0;i<m;i++)
|
||||
{
|
||||
int u,v,w; scanf("%d%d%d",&u,&v,&w);
|
||||
AddEdge(u,v,w);
|
||||
AddEdge(v,u,w);
|
||||
}
|
||||
for(int i=1;i<=n;i++) dist[i]=inf;
|
||||
dist[s]=0;
|
||||
priority_queue<QData> 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->w<dist[it->v])
|
||||
{
|
||||
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;
|
||||
}
|
60
ACMOJ-1717.cpp
Normal file
60
ACMOJ-1717.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
#include<cassert>
|
||||
#include<string>
|
||||
#include<cstdio>
|
||||
#include<queue>
|
||||
#include<map>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
unordered_map<LL,int> 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;
|
||||
}
|
41
ACMOJ-1728.hpp
Normal file
41
ACMOJ-1728.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
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;
|
||||
}
|
60
ACMOJ-1729.hpp
Normal file
60
ACMOJ-1729.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
using namespace std;
|
||||
|
||||
void Init(char **&p, int n) { // 初始化,n为string的个数,传入的p指向nullptr
|
||||
// todo
|
||||
p = new char *[n + 1];
|
||||
p[0] = reinterpret_cast<char *>(new int[n + 1]);
|
||||
for (int i = 1; i <= n; i++) reinterpret_cast<int *>(p[0])[i] = 0;
|
||||
reinterpret_cast<int *>(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<int *>(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<int *>(p[0])[z] =
|
||||
reinterpret_cast<int *>(p[0])[x] + reinterpret_cast<int *>(p[0])[y];
|
||||
delete[] p[z];
|
||||
p[z] = new char[reinterpret_cast<int *>(p[0])[z] + 1];
|
||||
memcpy(p[z], p[x], reinterpret_cast<int *>(p[0])[x]);
|
||||
memcpy(p[z] + reinterpret_cast<int *>(p[0])[x], p[y],
|
||||
reinterpret_cast<int *>(p[0])[y]);
|
||||
p[z][reinterpret_cast<int *>(p[0])[z]] = 0;
|
||||
}
|
||||
void Double_String(
|
||||
char **&p, int x) { // 把第x个string复制两遍前后拼接起来,再赋给第x个string
|
||||
// todo
|
||||
char *new_p = new char[reinterpret_cast<int *>(p[0])[x] * 2 + 1];
|
||||
memcpy(new_p, p[x], reinterpret_cast<int *>(p[0])[x]);
|
||||
memcpy(new_p + reinterpret_cast<int *>(p[0])[x], p[x],
|
||||
reinterpret_cast<int *>(p[0])[x]);
|
||||
reinterpret_cast<int *>(p[0])[x] *= 2;
|
||||
delete[] p[x];
|
||||
p[x] = new_p;
|
||||
p[x][reinterpret_cast<int *>(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<int *>(p[0]));
|
||||
delete[] p;
|
||||
}
|
58
ACMOJ-1741.cpp
Normal file
58
ACMOJ-1741.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
struct ElementType {
|
||||
int r, c, p;
|
||||
ElementType() {}
|
||||
ElementType(int __r, int __c, int __p) : r(__r), c(__c), p(__p) {}
|
||||
};
|
||||
vector<ElementType> 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;
|
||||
}
|
294
ACMOJ-1795.cpp
Normal file
294
ACMOJ-1795.cpp
Normal file
@ -0,0 +1,294 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#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 <typename T>
|
||||
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 <typename T>
|
||||
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 <typename T, typename... Args>
|
||||
inline int read(T &t, Args &...args) {
|
||||
return read(t) + read(args...);
|
||||
}
|
||||
template <typename T, typename... Args>
|
||||
inline void write(T t, Args... args) {
|
||||
write(t);
|
||||
write(args...);
|
||||
}
|
||||
#else
|
||||
template <typename A_t, typename B_t>
|
||||
inline int read(A_t &a, B_t &b) {
|
||||
return read(a) + read(b);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t>
|
||||
inline int read(A_t &a, B_t &b, C_t &c) {
|
||||
return read(a) + read(b) + read(c);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t, typename D_t>
|
||||
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 <typename A_t, typename B_t>
|
||||
inline void write(A_t a, B_t b) {
|
||||
write(a);
|
||||
write(b);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t>
|
||||
inline void write(A_t a, B_t b, C_t c) {
|
||||
write(a);
|
||||
write(b);
|
||||
write(c);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t, typename D_t>
|
||||
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<int> 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;
|
||||
}
|
138
ACMOJ-1941.cpp
Normal file
138
ACMOJ-1941.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
#include<cassert>
|
||||
#include<cstdio>
|
||||
#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<typename T> 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<typename T> 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<typename T,typename... Args> inline int read(T& t,Args&... args) { return read(t)+read(args...); }
|
||||
template<typename T,typename... Args> inline void write(T t,Args... args) { write(t); write(args...); }
|
||||
#else
|
||||
template<typename A_t,typename B_t> inline int read(A_t &a,B_t &b) { return read(a)+read(b); }
|
||||
template<typename A_t,typename B_t,typename C_t> inline int read(A_t &a,B_t &b,C_t &c) { return read(a)+read(b)+read(c); }
|
||||
template<typename A_t,typename B_t,typename C_t,typename D_t> 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<typename A_t,typename B_t> inline void write(A_t a,B_t b) { write(a); write(b); }
|
||||
template<typename A_t,typename B_t,typename C_t> inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); }
|
||||
template<typename A_t,typename B_t,typename C_t,typename D_t> 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<maxn*2;i++) Factor[i]=(Factor[i-1]*i)%mod;
|
||||
for(int i=1;i<=N;i++) read(r[i]);
|
||||
if(type==0) printf("%d\n",solve0());
|
||||
else printf("%d\n",solve1());
|
||||
return 0;
|
||||
}
|
36
ACMOJ-1948.cpp
Normal file
36
ACMOJ-1948.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
#include<cassert>
|
||||
#include<string>
|
||||
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<n;i++)
|
||||
{
|
||||
int loc=inf;
|
||||
for(int j=1;j<=3;j++)
|
||||
if(j!=s[i]-'0')
|
||||
loc=min(loc,pos[j]);
|
||||
pos[s[i]-'0']=i;
|
||||
if(loc>=0) res=min(res,i-loc+1);
|
||||
}
|
||||
printf("%d\n",res==inf?0:res);
|
||||
}
|
||||
return 0;
|
||||
}
|
50
ACMOJ-1954.cpp
Normal file
50
ACMOJ-1954.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
#include<cassert>
|
||||
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;
|
||||
}
|
146
ACMOJ-1981.cpp
Normal file
146
ACMOJ-1981.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
#include<cassert>
|
||||
#include<string>
|
||||
#include<cstdio>
|
||||
#include<queue>
|
||||
#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<typename T> 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<typename T> 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<typename T,typename... Args> inline int read(T& t,Args&... args) { return read(t)+read(args...); }
|
||||
template<typename T,typename... Args> inline void write(T t,Args... args) { write(t); write(args...); }
|
||||
#else
|
||||
template<typename A_t,typename B_t> inline int read(A_t &a,B_t &b) { return read(a)+read(b); }
|
||||
template<typename A_t,typename B_t,typename C_t> inline int read(A_t &a,B_t &b,C_t &c) { return read(a)+read(b)+read(c); }
|
||||
template<typename A_t,typename B_t,typename C_t,typename D_t> 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<typename A_t,typename B_t> inline void write(A_t a,B_t b) { write(a); write(b); }
|
||||
template<typename A_t,typename B_t,typename C_t> inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); }
|
||||
template<typename A_t,typename B_t,typename C_t,typename D_t> 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<m;i++)
|
||||
{
|
||||
int a,b; read(a,b);
|
||||
AddEdge(a,b);
|
||||
AddEdge(b,a);
|
||||
}
|
||||
for(int i=1;i<=n;i++) dist[i]=inf;
|
||||
dist[1]=0;
|
||||
queue<int> 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]+1<dist[it->v])
|
||||
{
|
||||
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<m*2;i++) res+=buf[i].deleteable;
|
||||
write(res/2,'\n');
|
||||
return 0;
|
||||
}
|
59
ACMOJ-1998.cpp
Normal file
59
ACMOJ-1998.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include<cstdio>
|
||||
#include<unordered_map>
|
||||
#include<cstring>
|
||||
#include<queue>
|
||||
#include<algorithm>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
const LL KEndStatus=123804765;
|
||||
unordered_map<LL,int> res;
|
||||
int main()
|
||||
{
|
||||
#ifdef local
|
||||
freopen("pro.in","r",stdin);
|
||||
#endif
|
||||
res[KEndStatus]=0;
|
||||
queue<LL> 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;
|
||||
}
|
75
ACMOJ-1999.cpp
Normal file
75
ACMOJ-1999.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include<cstdio>
|
||||
#include<unordered_map>
|
||||
#include<cstring>
|
||||
#include<queue>
|
||||
#include<algorithm>
|
||||
#include<cassert>
|
||||
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;
|
||||
}
|
122
ACMOJ-2000.cpp
Normal file
122
ACMOJ-2000.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
#include<cstdio>
|
||||
#include<algorithm>
|
||||
#pragma once
|
||||
#include<cstdio>
|
||||
#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<typename T> 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<typename T> 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<typename T,typename... Args> inline int read(T& t,Args&... args) { return read(t)+read(args...); }
|
||||
template<typename T,typename... Args> inline void write(T t,Args... args) { write(t); write(args...); }
|
||||
#else
|
||||
template<typename A_t,typename B_t> inline int read(A_t &a,B_t &b) { return read(a)+read(b); }
|
||||
template<typename A_t,typename B_t,typename C_t> inline int read(A_t &a,B_t &b,C_t &c) { return read(a)+read(b)+read(c); }
|
||||
template<typename A_t,typename B_t,typename C_t,typename D_t> 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<typename A_t,typename B_t> inline void write(A_t a,B_t b) { write(a); write(b); }
|
||||
template<typename A_t,typename B_t,typename C_t> inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); }
|
||||
template<typename A_t,typename B_t,typename C_t,typename D_t> 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;
|
||||
}
|
212
ACMOJ-2001.cpp
Normal file
212
ACMOJ-2001.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
#pragma once
|
||||
#include<cstdio>
|
||||
#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<typename T> 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<typename T> 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<typename T,typename... Args> inline int read(T& t,Args&... args) { return read(t)+read(args...); }
|
||||
template<typename T,typename... Args> inline void write(T t,Args... args) { write(t); write(args...); }
|
||||
#else
|
||||
template<typename A_t,typename B_t> inline int read(A_t &a,B_t &b) { return read(a)+read(b); }
|
||||
template<typename A_t,typename B_t,typename C_t> inline int read(A_t &a,B_t &b,C_t &c) { return read(a)+read(b)+read(c); }
|
||||
template<typename A_t,typename B_t,typename C_t,typename D_t> 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<typename A_t,typename B_t> inline void write(A_t a,B_t b) { write(a); write(b); }
|
||||
template<typename A_t,typename B_t,typename C_t> inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); }
|
||||
template<typename A_t,typename B_t,typename C_t,typename D_t> 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<cstdio>
|
||||
#include<algorithm>
|
||||
#include<vector>
|
||||
#include<cstring>
|
||||
#include<cassert>
|
||||
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]<size[b]) swap(a,b);
|
||||
fa[b]=a;
|
||||
size[a]+=size[b];
|
||||
}
|
||||
} DSU;
|
||||
struct RawEdge
|
||||
{
|
||||
int u,v,w;
|
||||
};
|
||||
inline bool operator<(const RawEdge &a,const RawEdge &b) { return a.w>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<RawEdge> 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<<i))
|
||||
{
|
||||
res=min(res,min_up[x][i]);
|
||||
x=anc[x][i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
#ifdef local
|
||||
freopen("pro.in","r",stdin);
|
||||
#endif
|
||||
read(n,m);
|
||||
for(int i=0;i<m;i++)
|
||||
{
|
||||
int u,v,w; read(u,v,w);
|
||||
rawG.push_back(RawEdge({u,v,w}));
|
||||
}
|
||||
sort(rawG.begin(),rawG.end());
|
||||
DSU.init(n);
|
||||
for(int i=0;i<rawG.size();i++)
|
||||
{
|
||||
int u=rawG[i].u,v=rawG[i].v,w=rawG[i].w;
|
||||
u=DSU.GetRoot(u);
|
||||
v=DSU.GetRoot(v);
|
||||
if(u==v) continue;
|
||||
DSU.Merge(u,v);
|
||||
AddEdge(u,v,w);
|
||||
AddEdge(v,u,w);
|
||||
}
|
||||
for(int i=1;i<=n;i++) root[i]=DSU.GetRoot(i);
|
||||
memset(min_up,0x3f,sizeof(min_up));
|
||||
for(int i=1;i<=n;i++)
|
||||
if(!vis[i])
|
||||
InitData(root[i],0);
|
||||
LL final_res=0;
|
||||
int q; read(q);
|
||||
for(int i=1;i<=q;i++)
|
||||
{
|
||||
int x,y; read(x,y);
|
||||
if(root[x]!=root[y]) continue;
|
||||
int lca=GetLCA(x,y);
|
||||
final_res^=LL(i)*min(GetRoute(x,lca),GetRoute(y,lca));
|
||||
}
|
||||
printf("%lld\n",final_res);
|
||||
return 0;
|
||||
}
|
186
ACMOJ-2002.cpp
Normal file
186
ACMOJ-2002.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
#include<cstdio>
|
||||
#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<typename T> 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<typename T> 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<typename T,typename... Args> inline int read(T& t,Args&... args) { return read(t)+read(args...); }
|
||||
template<typename T,typename... Args> inline void write(T t,Args... args) { write(t); write(args...); }
|
||||
#else
|
||||
template<typename A_t,typename B_t> inline int read(A_t &a,B_t &b) { return read(a)+read(b); }
|
||||
template<typename A_t,typename B_t,typename C_t> inline int read(A_t &a,B_t &b,C_t &c) { return read(a)+read(b)+read(c); }
|
||||
template<typename A_t,typename B_t,typename C_t,typename D_t> 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<typename A_t,typename B_t> inline void write(A_t a,B_t b) { write(a); write(b); }
|
||||
template<typename A_t,typename B_t,typename C_t> inline void write(A_t a,B_t b,C_t c) { write(a); write(b); write(c); }
|
||||
template<typename A_t,typename B_t,typename C_t,typename D_t> 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<cstdio>
|
||||
#include<algorithm>
|
||||
#include<unordered_map>
|
||||
#include<cassert>
|
||||
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<pair<int,int>> query[maxn];
|
||||
struct Data
|
||||
{
|
||||
vector<int> colors;
|
||||
unordered_map<int,int> mp;
|
||||
vector<int> 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<query[u].size();i++)
|
||||
{
|
||||
int id=query[u][i].first,k=query[u][i].second;
|
||||
if(k==1) res[id]=1;
|
||||
}
|
||||
return this_data;
|
||||
}
|
||||
vector<Data*> 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;i<sub_data.size();i++)
|
||||
{
|
||||
Data *p=sub_data[i];
|
||||
for(int j=0;j<p->colors.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<query[u].size();i++)
|
||||
{
|
||||
int id=query[u][i].first,k=query[u][i].second;
|
||||
if(k>=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;
|
||||
}
|
91
ACMOJ-2007.cpp
Normal file
91
ACMOJ-2007.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <random>
|
||||
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;
|
||||
}
|
330
ACMOJ-2010.cpp
Normal file
330
ACMOJ-2010.cpp
Normal file
@ -0,0 +1,330 @@
|
||||
#include <cstdio>
|
||||
#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 <typename T>
|
||||
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 <typename T>
|
||||
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 <typename T, typename... Args>
|
||||
inline int read(T &t, Args &...args) {
|
||||
return read(t) + read(args...);
|
||||
}
|
||||
template <typename T, typename... Args>
|
||||
inline void write(T t, Args... args) {
|
||||
write(t);
|
||||
write(args...);
|
||||
}
|
||||
#else
|
||||
template <typename A_t, typename B_t>
|
||||
inline int read(A_t &a, B_t &b) {
|
||||
return read(a) + read(b);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t>
|
||||
inline int read(A_t &a, B_t &b, C_t &c) {
|
||||
return read(a) + read(b) + read(c);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t, typename D_t>
|
||||
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 <typename A_t, typename B_t>
|
||||
inline void write(A_t a, B_t b) {
|
||||
write(a);
|
||||
write(b);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t>
|
||||
inline void write(A_t a, B_t b, C_t c) {
|
||||
write(a);
|
||||
write(b);
|
||||
write(c);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t, typename D_t>
|
||||
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 <algorithm>
|
||||
#include <cassert>
|
||||
#include <set>
|
||||
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<int> 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
|
||||
*/
|
153
ACMOJ-2031.cpp
Normal file
153
ACMOJ-2031.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
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;
|
||||
}
|
116
ACMOJ-2032.cpp
Normal file
116
ACMOJ-2032.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <queue>
|
||||
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;
|
||||
}
|
53
ACMOJ-2033.cpp
Normal file
53
ACMOJ-2033.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
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;
|
||||
}
|
338
ACMOJ-2037.cpp
Normal file
338
ACMOJ-2037.cpp
Normal file
@ -0,0 +1,338 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#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 <typename T>
|
||||
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 <typename T>
|
||||
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 <typename T, typename... Args>
|
||||
inline int read(T &t, Args &...args) {
|
||||
return read(t) + read(args...);
|
||||
}
|
||||
template <typename T, typename... Args>
|
||||
inline void write(T t, Args... args) {
|
||||
write(t);
|
||||
write(args...);
|
||||
}
|
||||
#else
|
||||
template <typename A_t, typename B_t>
|
||||
inline int read(A_t &a, B_t &b) {
|
||||
return read(a) + read(b);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t>
|
||||
inline int read(A_t &a, B_t &b, C_t &c) {
|
||||
return read(a) + read(b) + read(c);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t, typename D_t>
|
||||
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 <typename A_t, typename B_t>
|
||||
inline void write(A_t a, B_t b) {
|
||||
write(a);
|
||||
write(b);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t>
|
||||
inline void write(A_t a, B_t b, C_t c) {
|
||||
write(a);
|
||||
write(b);
|
||||
write(c);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t, typename D_t>
|
||||
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;
|
||||
}
|
146
ACMOJ-2045.cpp
Normal file
146
ACMOJ-2045.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
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;
|
||||
}
|
73
ACMOJ-2050.cpp
Normal file
73
ACMOJ-2050.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
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;
|
||||
}
|
66
ACMOJ-2057.cpp
Normal file
66
ACMOJ-2057.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
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;
|
||||
}
|
78
ACMOJ-2058.cpp
Normal file
78
ACMOJ-2058.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
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;
|
||||
}
|
86
ACMOJ-2059.h
Normal file
86
ACMOJ-2059.h
Normal file
@ -0,0 +1,86 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class Student {
|
||||
public:
|
||||
static std::map<int, Student *> id2student;
|
||||
static std::map<std::string, Student *> 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");
|
||||
}
|
||||
};
|
78
ACMOJ-2065.cpp
Normal file
78
ACMOJ-2065.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
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<int> 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;
|
||||
}
|
164
ACMOJ-2069.hpp
Normal file
164
ACMOJ-2069.hpp
Normal file
@ -0,0 +1,164 @@
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
struct dynamic_bitset {
|
||||
int len = 0;
|
||||
typedef unsigned long long ULL;
|
||||
std::vector<ULL> 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;
|
||||
}
|
||||
};
|
17
ACMOJ-2073.cpp
Normal file
17
ACMOJ-2073.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "ACMOJ-2073.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
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;
|
||||
}
|
95
ACMOJ-2073.hpp
Normal file
95
ACMOJ-2073.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
// 你需要在代码中 #include "utility.h"
|
||||
// 你可以使用这个模板库的函数
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "utility.h"
|
||||
namespace sjtu {
|
||||
|
||||
template <typename... Args>
|
||||
std::string format(std::string_view fmt, Args &&...args) {
|
||||
std::vector<std::string> vec = make_string(std::forward<Args>(args)...);
|
||||
std::string ret;
|
||||
std::vector<int> arg_seq;
|
||||
std::vector<std::string> str_seq;
|
||||
std::stack<int> 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
|
193
ACMOJ-2080.cpp
Normal file
193
ACMOJ-2080.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
#include <bits/stdc++.h>
|
||||
#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 <typename T>
|
||||
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 <typename T>
|
||||
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 <typename T, typename... Args>
|
||||
inline int read(T &t, Args &...args) {
|
||||
return read(t) + read(args...);
|
||||
}
|
||||
template <typename T, typename... Args>
|
||||
inline void write(T t, Args... args) {
|
||||
write(t);
|
||||
write(args...);
|
||||
}
|
||||
#else
|
||||
template <typename A_t, typename B_t>
|
||||
inline int read(A_t &a, B_t &b) {
|
||||
return read(a) + read(b);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t>
|
||||
inline int read(A_t &a, B_t &b, C_t &c) {
|
||||
return read(a) + read(b) + read(c);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t, typename D_t>
|
||||
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 <typename A_t, typename B_t>
|
||||
inline void write(A_t a, B_t b) {
|
||||
write(a);
|
||||
write(b);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t>
|
||||
inline void write(A_t a, B_t b, C_t c) {
|
||||
write(a);
|
||||
write(b);
|
||||
write(c);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t, typename D_t>
|
||||
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;
|
||||
}
|
60
ACMOJ-2081.cpp
Normal file
60
ACMOJ-2081.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
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;
|
||||
}
|
22
ACMOJ-2090.cpp
Normal file
22
ACMOJ-2090.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "2090.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
signed main() {
|
||||
sjtu::any_ptr a = sjtu::make_any_ptr(int(1));
|
||||
sjtu::any_ptr b = a;
|
||||
|
||||
a.unwrap<int>() = 2;
|
||||
std::cerr << b.unwrap<int>() << std::endl; // 2
|
||||
b = new std::string;
|
||||
b.unwrap<std::string>() = "Hello, world!";
|
||||
std::cerr << b.unwrap<std::string>() << std::endl; // Hello, world!
|
||||
|
||||
try {
|
||||
a.unwrap<std::string>() = "a";
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << e.what() << std::endl; // bad cast
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
162
ACMOJ-2090.hpp
Normal file
162
ACMOJ-2090.hpp
Normal file
@ -0,0 +1,162 @@
|
||||
#ifndef SRC_HPP
|
||||
#define SRC_HPP
|
||||
|
||||
#include <initializer_list>
|
||||
#include <stdexcept>
|
||||
// 以上是你所需要的头文件,如果你想使用其它头文件,请询问助教
|
||||
// 禁止使用 std::shared_ptr 与 std::any
|
||||
|
||||
namespace sjtu {
|
||||
|
||||
class any_ptr {
|
||||
class Info_Base {
|
||||
public:
|
||||
int counter;
|
||||
virtual ~Info_Base() {}
|
||||
};
|
||||
template <class T>
|
||||
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<int> = 2;
|
||||
* std::cout << b << std::endl; // 2
|
||||
* @param other
|
||||
*/
|
||||
any_ptr(const any_ptr &other) {
|
||||
info = other.info;
|
||||
if (info) info->counter++;
|
||||
}
|
||||
template <class T>
|
||||
any_ptr(T *ptr) {
|
||||
info = new Info<T>(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 <class T>
|
||||
any_ptr &operator=(T *ptr) {
|
||||
if (info) {
|
||||
info->counter--;
|
||||
if (info->counter == 0) {
|
||||
delete info;
|
||||
}
|
||||
}
|
||||
info = new Info<T>(ptr);
|
||||
info->counter = 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取该对象指向的值的引用
|
||||
* @note 若该对象指向的值不是 T 类型,则抛出异常 std::bad_cast
|
||||
* @example
|
||||
* any_ptr a = make_any_ptr(1);
|
||||
* std::cout << a.unwrap<int>() << std::endl; // 1
|
||||
* @tparam T
|
||||
* @return T&
|
||||
*/
|
||||
template <class T>
|
||||
T &unwrap() {
|
||||
Info<T> *info_t = dynamic_cast<Info<T> *>(info);
|
||||
if (info_t)
|
||||
return *(info_t->ptr);
|
||||
else
|
||||
throw std::bad_cast();
|
||||
}
|
||||
// 某一个 any_ptr 类对象可能为 const,请你补充 unwrap 函数
|
||||
template <class T>
|
||||
const T &unwrap() const {
|
||||
Info<T> *info_t = dynamic_cast<Info<T> *>(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<std::vector<int>>(1, 2, 3);
|
||||
* any_ptr m = make_any_ptr<std::map<int, int>>({{1, 2}, {3, 4}});
|
||||
* @tparam T
|
||||
* @param t
|
||||
* @return any_ptr
|
||||
*/
|
||||
template <class T>
|
||||
any_ptr make_any_ptr(const T &t) {
|
||||
return any_ptr(new T(t));
|
||||
}
|
||||
// 某些 any_ptr 类对象可能由不定长参数或初始化列表构造,请你参照上方的 example
|
||||
// 补充 make_any_ptr 函数,我们会有一个特殊的测试点测试你的程序是否完成要求
|
||||
template <class T, class... Args>
|
||||
any_ptr make_any_ptr(Args... args) {
|
||||
return any_ptr(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
} // namespace sjtu
|
||||
|
||||
#endif
|
199
ACMOJ-2091.cpp
Normal file
199
ACMOJ-2091.cpp
Normal file
@ -0,0 +1,199 @@
|
||||
#include <cstdio>
|
||||
#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 <typename T>
|
||||
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 <typename T>
|
||||
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 <typename T, typename... Args>
|
||||
inline int read(T &t, Args &...args) {
|
||||
return read(t) + read(args...);
|
||||
}
|
||||
template <typename T, typename... Args>
|
||||
inline void write(T t, Args... args) {
|
||||
write(t);
|
||||
write(args...);
|
||||
}
|
||||
#else
|
||||
template <typename A_t, typename B_t>
|
||||
inline int read(A_t &a, B_t &b) {
|
||||
return read(a) + read(b);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t>
|
||||
inline int read(A_t &a, B_t &b, C_t &c) {
|
||||
return read(a) + read(b) + read(c);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t, typename D_t>
|
||||
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 <typename A_t, typename B_t>
|
||||
inline void write(A_t a, B_t b) {
|
||||
write(a);
|
||||
write(b);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t>
|
||||
inline void write(A_t a, B_t b, C_t c) {
|
||||
write(a);
|
||||
write(b);
|
||||
write(c);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t, typename D_t>
|
||||
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 <vector>
|
||||
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<int> 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;
|
||||
}
|
51
ACMOJ-2095.cpp
Normal file
51
ACMOJ-2095.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include "ACMOJ-2095.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
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<int> ptr1(new int(114514));
|
||||
|
||||
// 移交所有权
|
||||
unique_ptr<int> ptr2(std::move(ptr1));
|
||||
|
||||
// 释放所有权
|
||||
int *tmp = ptr2.release();
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
void test1() {
|
||||
using sjtu::unique_ptr;
|
||||
unique_ptr<koishi> ptr1 = sjtu::make_unique<koishi>(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;
|
||||
}
|
101
ACMOJ-2095.hpp
Normal file
101
ACMOJ-2095.hpp
Normal file
@ -0,0 +1,101 @@
|
||||
#pragma once
|
||||
#include <new>
|
||||
#include <utility>
|
||||
// 你不可以使用其他任何头文件
|
||||
|
||||
namespace sjtu {
|
||||
|
||||
/**
|
||||
* @brief 一个可以在离开作用域之后自动归还内存的指针。
|
||||
* unique_ptr <_Tp> 行为应该和普通指针 _Tp * 几乎一致。
|
||||
* @tparam _Tp 模板参数,指针指向的类型。
|
||||
*/
|
||||
template <typename _Tp>
|
||||
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<int>) <= sizeof(void *));
|
||||
|
||||
// // 创建一个 unique_ptr,指向一个用 new 分配的 _Tp 对象
|
||||
// template <typename _Tp>
|
||||
// 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 <typename _Tp, typename... Args>
|
||||
unique_ptr<_Tp> make_unique(Args &&...args) {
|
||||
return std::move(unique_ptr<_Tp>(new _Tp(std::forward<Args>(args)...)));
|
||||
}
|
||||
} // namespace sjtu
|
32
ACMOJ-2096.cpp
Normal file
32
ACMOJ-2096.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include <iostream>
|
||||
#include "ACMOJ-2096.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
signed main() {
|
||||
using koishi::any;
|
||||
any x;
|
||||
x = 1919810;
|
||||
std::cout << x.cast <int> () << std::endl;
|
||||
x = 114.514;
|
||||
|
||||
try {
|
||||
std::cout << x.cast <int> () << std::endl;
|
||||
} catch (const std::exception &e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
|
||||
auto ptr = x.try_cast <double> ();
|
||||
if (ptr) std::cout << "Double value: " << *ptr << std::endl;
|
||||
// if C++ 17 or later, try this:
|
||||
// if (auto ptr = x.try_cast <double> ()) std::cout << "Double value: " << *ptr << std::endl;
|
||||
|
||||
any y {x};
|
||||
std::cout << y.cast <double> () << std::endl;
|
||||
|
||||
any z {std::move(x)};
|
||||
if (x.is_empty()) std::cout << "x is empty" << std::endl;
|
||||
|
||||
std::cout << z.cast <double> () << std::endl;
|
||||
return 0;
|
||||
}
|
138
ACMOJ-2096.hpp
Normal file
138
ACMOJ-2096.hpp
Normal file
@ -0,0 +1,138 @@
|
||||
#pragma once
|
||||
#include <new>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
// 你不可以使用任何其他的头文件
|
||||
|
||||
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 <typename T>
|
||||
struct storage : base {
|
||||
T value; // 真实的数据存储在这里哦
|
||||
|
||||
// 完美转发,接受任意类型的参数
|
||||
// 现在 storage 有 T 所有的构造函数了
|
||||
template <typename Args>
|
||||
storage(Args &&args) : value(std::forward<Args>(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 <typename T,
|
||||
typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, any>>>
|
||||
any(const T &val) {
|
||||
ptr = new storage<T>(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 <typename T>
|
||||
T &cast() {
|
||||
storage<T> *new_ptr = dynamic_cast<storage<T> *>(ptr);
|
||||
if (new_ptr != nullptr)
|
||||
return new_ptr->value;
|
||||
else
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
// 差不多,但是是 const 版本的。
|
||||
template <typename T>
|
||||
const T &cast() const {
|
||||
storage<T> *new_ptr = dynamic_cast<storage<T> *>(ptr);
|
||||
if (new_ptr != nullptr)
|
||||
return new_ptr->value;
|
||||
else
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
// 尝试把当前对象转换成 T 类型。
|
||||
// 如果当前存储的不是 T 类型的值,那么返回 nullptr
|
||||
template <typename T>
|
||||
T *try_cast() {
|
||||
storage<T> *new_ptr = dynamic_cast<storage<T> *>(ptr);
|
||||
if (new_ptr != nullptr)
|
||||
return &new_ptr->value;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 差不多,但是是 const 版本的。
|
||||
template <typename T>
|
||||
const T *try_cast() const {
|
||||
storage<T> *new_ptr = dynamic_cast<storage<T> *>(ptr);
|
||||
if (new_ptr != nullptr)
|
||||
return &new_ptr->value;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 判断当前对象是否为空。
|
||||
bool is_empty() const { return ptr == nullptr; }
|
||||
};
|
||||
|
||||
} /* namespace koishi */
|
11
ACMOJ1328.hpp
Normal file
11
ACMOJ1328.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include <iostream>
|
||||
void debugPrint() { std::cout << std::endl; }
|
||||
template <typename T>
|
||||
void debugPrint(T x) {
|
||||
std::cout << x << std::endl;
|
||||
}
|
||||
template <typename T, typename... Args>
|
||||
void debugPrint(T x, Args... args) {
|
||||
std::cout << x << " ";
|
||||
debugPrint(args...);
|
||||
}
|
93
Luogu-P1742.cpp
Normal file
93
Luogu-P1742.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <random>
|
||||
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;
|
||||
}
|
111
Luogu-P2346.cpp
Normal file
111
Luogu-P2346.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
using namespace std;
|
||||
typedef unsigned int UI;
|
||||
typedef long long LL;
|
||||
unordered_map<UI, int> 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<UI> 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;
|
||||
}
|
92
Luogu-P2533.cpp
Normal file
92
Luogu-P2533.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <random>
|
||||
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;
|
||||
}
|
Reference in New Issue
Block a user