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