鸽了建模队友的一晚,悄悄地写个 a t c o d e r atcoder atcoder没人发现吧?
悄悄地 a k ak ak,不让他们发现
略
略(水题)
/*** keep hungry and calm CoolGuang! ***/
//#pragma GCC optimize(3)
#include
#include
#include
#include
#include
#include
#include
#define debug(x) cout<<#x<<":"<
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e18+7;
const ll maxn = 1e5+700;
const int M = 1e6+8;
const ll mod= 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){
char c=getchar();T x=0,f=1;while(!isdigit(c)){
if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
int main(){
ll a,b,c;read(a);read(b);read(c);
if(c == 0){
if(a>b) printf("Takahashi\n");
else printf("Aoki\n");
}else{
if(b>a) printf("Aoki\n");
else printf("Takahashi\n");
}
return 0;
}
/**
**/
判断当前给出 s , t s,t s,t中是否存在 s < S s \lt S s<S, t < D t \lt D t<D的物品
水题
/*** keep hungry and calm CoolGuang! ***/
//#pragma GCC optimize(3)
#include
#include
#include
#include
#include
#include
#include
#define debug(x) cout<<#x<<":"<
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e18+7;
const ll maxn = 1e5+700;
const int M = 1e6+8;
const ll mod= 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){
char c=getchar();T x=0,f=1;while(!isdigit(c)){
if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
int main(){
ll S,D;
read(n);read(S);read(D);
int f = 0;
for(int i=1;i<=n;i++){
int x,y;read(x);read(y);
if(x<S && y>D) f = 1;
}
printf("%s\n",f?"Yes":"No");
return 0;
}
/**
5
N 83 2 7475
UN 83 2 27550
EXF 5 2 17298
OVYNH 51 2 14827
XNV 53 1 7591
2
1
XNV
2
83
**/
现在有 N N N个盘子
给出一些条件 ( A i , B i ) (A_i,B_i) (Ai,Bi),这个条件被满足当且仅当 A i , B i A_i,B_i Ai,Bi盘子中都有一件物品
现在有 K K K个人,可以向 C i , D i C_i,D_i Ci,Di中放一个物品,不能同时放只能放一个,问最多能满足几个条件?
主要考虑到 K ≤ 17 K \le 17 K≤17,所以直接暴力枚举 K K K的状态就好了
复杂度: O ( N ∗ 2 K ) O(N*2^K) O(N∗2K)
暴力判断每个状态的结果,最后求最优就好了。
/*** keep hungry and calm CoolGuang! ***/
//#pragma GCC optimize(3)
#include
#include
#include
#include
#include
#include
#include
#define debug(x) cout<<#x<<":"<
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e18+7;
const ll maxn = 1e6+700;
const int M = 2e5+8;
const ll mod= 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){
char c=getchar();T x=0,f=1;while(!isdigit(c)){
if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
struct node{
int x,y;
}q[maxn];
ll dp[maxn][20];///前i个线段形成以K结尾时最小长度
ll c[maxn];
ll w[maxn][2];
int vis[maxn];
int main(){
read(n);read(m);
for(int i=1;i<=m;i++){
read(q[i].x);
read(q[i].y);
}
read(p);
for(int i=0;i<p;i++){
read(w[i][0]);
read(w[i][1]);
}
int MAX = (1<<p);
int ans = 0;
for(int i=0;i<MAX;i++){
for(int k=0;k<p;k++){
int op = (i>>k&1);
vis[w[k][op]] = 1;
}
int res = 0;
for(int k=1;k<=m;k++){
if(vis[q[k].x] && vis[q[k].y])
res++;
}
ans = max(ans,res);
for(int k=1;k<=n;k++) vis[k] = 0;
}
di(ans);
return 0;
}
/**
5
N 83 2 7475
UN 83 2 27550
EXF 5 2 17298
OVYNH 51 2 14827
XNV 53 1 7591
2
1
XNV
2
83
**/
询问有多少公差为1的序列的是 N N N
公式题,首先看见数据范围 N ≤ 1 e 12 N \le 1e12 N≤1e12,考虑直接根号分解
推一下公式:
假设存在一段序列 [ l + 1 , r ] [l+1,r] [l+1,r]和是 N N N,那么满足:
r ∗ ( r + 1 ) 2 − l ∗ ( l + 1 ) 2 = N \frac{r*(r+1)}{2} - \frac{l*(l+1)}{2} = N 2r∗(r+1)−2l∗(l+1)=N
r ∗ ( r + 1 ) − l ∗ ( l + 1 ) = 2 ∗ N r*(r+1)-l*(l+1)=2*N r∗(r+1)−l∗(l+1)=2∗N
r ∗ r − l ∗ l + r − l = 2 ∗ N r*r - l*l +r-l = 2*N r∗r−l∗l+r−l=2∗N
( r − l ) ∗ ( r + l ) + ( r − l ) = 2 ∗ N (r-l)*(r+l)+(r-l) = 2*N (r−l)∗(r+l)+(r−l)=2∗N
( r − l ) ∗ ( r + l + 1 ) = 2 ∗ N (r-l)*(r+l+1) = 2*N (r−l)∗(r+l+1)=2∗N
根号分解因子,之后判断即可
/*** keep hungry and calm CoolGuang! ***/
//#pragma GCC optimize(3)
#include
#include
#include
#include
#include
#include
#include
#define debug(x) cout<<#x<<":"<
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e18+7;
const ll maxn = 1e5+700;
const int M = 1e6+8;
const ll mod= 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){
char c=getchar();T x=0,f=1;while(!isdigit(c)){
if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
map<pair<ll,ll>,int>mp;
int main(){
read(n);
n*=2;
ll ans = 0;
for(ll i=1;i*i<=n;i++){
if(n%i == 0){
ll tempx = i,tempy = n/i;
if((tempx+tempy-1)%2==0){
ll r = (tempx+tempy-1)/2;
ll l = (r-tempx);
if(!mp[{
l,r}]){
mp[{
l,r}] = 1;
ans ++;
}
}
tempy = i,tempx = n/i;
if((tempx+tempy-1)%2==0){
ll r = (tempx+tempy-1)/2;
ll l = (r-tempx);
if(!mp[{
l,r}]){
mp[{
l,r}] = 1;
ans ++;
}
}
}
}
dl(ans);
return 0;
}
/**
5
N 83 2 7475
UN 83 2 27550
EXF 5 2 17298
OVYNH 51 2 14827
XNV 53 1 7591
2
1
XNV
2
83
**/
给你 M M M个相连的数对,在生成的序列中只能用 M M M个相连的数对连接(数对不考虑顺序)。
给出 K K K个数,问包含K个数的
最小的
可以连接的
序列长度是多少
首先可以将数抽象为点,那么以 s s s开始以 t t t结束最少的序列长度,就可以由最短路求出。
所以首先预处理 K K K个点之间两两之间的最短路。
有了这个之后,观察K的范围 K ≤ 17 K \le 17 K≤17,所以直接最小权值哈密尔顿回路就好了.
/*** keep hungry and calm CoolGuang! ***/
//#pragma GCC optimize(3)
#include
#include
#include
#include
#include
#include
#include
#define debug(x) cout<<#x<<":"<
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e16+7;
const ll maxn = 1e6+700;
const int M = 2e5+8;
const ll mod= 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){
char c=getchar();T x=0,f=1;while(!isdigit(c)){
if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
ll dis[maxn];
struct N{
int id;
ll w;
bool friend operator<(N a,N b)
{
return a.w>b.w;
}
};
vector<pair<int,int>>v[maxn];
void dijstra(int st){
for(int i=1;i<=n;i++) dis[i]=INF;
dis[st]=0;
N s;s.id=st;s.w=0;
priority_queue<N>q;
q.push(s);
while(!q.empty()){
N u=q.top();q.pop();
if(dis[u.id]!=u.w) continue;
for(auto x:v[u.id]){
int e = x.first,w = x.second;
if(dis[e]>u.w+w){
dis[e]=u.w+w;
N now;now.id=e;
now.w=dis[e];
q.push(now);
}
}
}
return ;
}
ll c[maxn];
ll mp[20][20];
ll s[20][1<<18];
int main(){
read(n);read(m);
for(int i=1;i<=m;i++){
int x,y;read(x);read(y);
v[x].push_back({
y,1});
v[y].push_back({
x,1});
}
read(p);
for(int i=1;i<=p;i++) read(c[i]);
for(int i=1;i<=p;i++){
dijstra(c[i]);
for(int k=i+1;k<=p;k++){
mp[i-1][k-1] = mp[k-1][i-1] = dis[c[k]];
}
}
int MAX = 1<<p;
for(int i=0;i<p;i++)
for(int k=0;k<MAX;k++)
s[i][k] = INF;
for(int i=0;i<p;i++) s[i][1<<i] = 0;
for(int i=1;i<MAX;i++){
for(int k=0;k<p;k++){
for(int j=0;j<p;j++){
if(j == k) continue;
if(i>>j&1) continue;
s[j][i|(1<<j)] = min(s[j][i|(1<<j)],s[k][i]+mp[k][j]);
}
}
}
ll ans = INF;
for(int i=0;i<p;i++)
ans = min(ans,s[i][MAX-1]);
if(ans>=INF) printf("-1\n",ans);
else printf("%lld\n",ans+1);
return 0;
}
/**
5
N 83 2 7475
UN 83 2 27550
EXF 5 2 17298
OVYNH 51 2 14827
XNV 53 1 7591
2
1
XNV
2
83
**/
初始给出一个序列 N N N,可以看成一个环。
输出 N N N行:
第 i i i行代表从 i i i开始 N N N个数字的序列逆序对数。
首先将i = 1的逆序对数求出
观察接下来的变化,每次移动都是将第1个放到最后
也就是说:
问题就解决啦。
/*** keep hungry and calm CoolGuang! ***/
//#pragma GCC optimize(3)
#include
#include
#include
#include
#include
#include
#include
#define debug(x) cout<<#x<<":"<
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e18+7;
const ll maxn = 1e5+700;
const int M = 1e6+8;
const ll mod= 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){
char c=getchar();T x=0,f=1;while(!isdigit(c)){
if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
ll a[maxn];
ll sum[maxn];
void add(int pos){
while(pos<=n){
sum[pos]++;
pos += pos&-pos;
}
}
ll query(int pos){
ll ans = 0;
while(pos){
ans += sum[pos];
pos -= pos&-pos;
}return ans;
}
int main(){
read(n);
for(int i=1;i<=n;i++){
read(a[i]);
a[i]++;
}
ll ans = 0;
for(int i=1;i<=n;i++){
ans += query(n)-query(a[i]);
add(a[i]);
}
dl(ans);
for(int i=1;i<=n;i++){
ans += query(n)-query(a[i])-query(a[i]-1);
dl(ans);
}
return 0;
}
/**
5
N 83 2 7475
UN 83 2 27550
EXF 5 2 17298
OVYNH 51 2 14827
XNV 53 1 7591
2
1
XNV
2
83
**/