技巧
对拍
正确的程序(daan)
#include <iostream>
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
cout << a+b << endl;
return 0;
}
需要测试的程序(yuan)
#include <stdio.h>
int main()
{
int a, b;
scanf("%d %d",&a, &b);
printf("%d\n", a+b);
return 0;
}
数据生成(data)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <algorithm>
#include <windows.h>
using namespace std;
int main()
{
srand(time(0));
int a,b;
a=rand()%100+1,b=rand()%100+1;
printf("%d %d\n",a,b);
return 0;
}
对拍
#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
while(1)
{
system("data.exe > data.txt");
system("daan.exe < data.txt > daan.txt");
system("yuan.exe < data.txt > yuan.txt");
if(system("fc yuan.txt daan.txt")) break;
}
return 0;
}
全部生成的exe文件放在一起,运行duipai.exe
模拟退火
P1337 [JSOI2004] 平衡点 / 吊打XXX(交了21次才调对)
t越大越准,jiang越大越准,run()跑的次数越多越准
建议t不要大于1e9,run()五次左右,jiang能不T的话最好0.999
#include<bits/stdc++.h>
#define for1(i,a,b) for(int i = a;i<=b;i++)
#define ll long long
#define mp(a,b) make_pair(a,b)
using namespace std;
struct node{
int x;
int y;
int w;
}a[500005];
int n,m;
double ansx,ansy;
double ans=1e18+7,t;
const double jiang=0.994;//降温系数
double cl(double x,double y)//这个我也看不懂,简单来说就是计算答案
{
double sum=0;
for(int i=1;i<=n;i++)
{
double dx=x-a[i].x;
double dy=y-a[i].y;
sum+=(sqrt(dx*dx+dy*dy))*a[i].w;
//物重一定,绳子越短,重物越低,势能越小
//势能又与物重成正比
}
return sum;//在(nowx,nowy)处的总势能
}
void run()
{
double jx=ansx;
double jy=ansy;
t=1e9;
while(t>1e-15)
{
double xinx=ansx+(rand()*2-RAND_MAX)*t;
double xiny=ansy+(rand()*2-RAND_MAX)*t;
double xinans=cl(xinx,xiny);
double de=xinans-ans;
if(de<0)//更优
{
jx=xinx;
jy=xiny;//就接受
ansx=jx;
ansy=jy;
ans=xinans;
}
else if(exp(-de/t)*RAND_MAX>rand())//看看是否有概率接受
{
jx=xinx;
jy=xiny;
}
t*=jiang;//降温
}
}
void sa()
{
run();
run();
run();
run();
}
int main() {
cin>>n;
for1(i,1,n)
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);
ansx/=n;//以平均数作为初始答案
ansy/=n;
ans=cl(ansx,ansy);
sa();
printf("%.3lf %.3lf",ansx,ansy);
return 0;
}
离散化
https://www.cnblogs.com/yyx525jia/p/16735119.html
珂朵莉树(ODT)
本质上其实就是一个去重的暴力
可以学习到一些炫酷的代码打法
#include<bits/stdc++.h>
#define s_it set<node>::iterator //s_it = set_iterator
#define for1(i,a,b) for(int i=a;i<=b;i++)
#define mp(a,b) make_pair(a,b)
using namespace std;
typedef long long type;
const int MOD7 = 1e9 + 7;
const int MOD9 = 1e9 + 9;
const int imax_n = 1e5 + 7;
struct node
{
int l;
int r;
mutable type val;
node(int a,int b = 0, type c = 0);
};
node::node(int a,int b, type c)
{
l = a;
r = b;
val = c;
}
bool operator <(const node &a,const node &b)
{
return a.l<b.l;
}
set<node> s;
s_it split(int pos)//找到一个区间里含有pos这个位置的点
{
s_it it = s.lower_bound(node(pos));//默认参数r与cal为0
if (it != s.end() && it->l == pos)//如果左端点就是或者找不到
return it;
//否则就要分裂成两个区间
--it;
unsigned int l = it->l, r = it->r;
type val = it->val;
s.erase(it);
s.insert(node(l, pos - 1, val));
return s.insert(node(pos, r, val)).first;//first 返回地址 secon的返回是否被插入成功
}
void assign(int l,int r, type val)//把l到r全部赋值成val的操作
{
s_it itr = split(r + 1), itl = split(l);//访问区间l-r
//必须先声明it2,因为it1在前的话地址可能会失效
s.erase(itl, itr);
s.insert(node(l, r, val));//l到r的整个区间全部变成一个点
return;
}
void add(int l, int r, type val)//区间加
{
s_it itr = split(r+1),itl = split(l);
for (; itl != itr; ++itl) //访问区间l到r标准套路
itl->val += val;
}
type ranks(int l, int r, int k)//区间第k小
{
vector<pair<type, int> > ji;
s_it itr = split(r+1),itl = split(l);
ji.clear();
pair<type,int> jl;
for (; itl != itr; ++itl)
{
jl=mp(itl->val, (itl->r)-(itl->l)+1);//权值与区间长度
ji.push_back(jl);
}
sort(ji.begin(), ji.end());//按权值排序
vector<pair<type,int> >::iterator it=ji.begin();
for (;it!=ji.end();++it)
{
k -= it->second;
if (k <= 0)
return it->first;
}
}
type pown(type a, type b, type mod)//快速幂 1
{
type res = 1;
type ans = a % mod;
while (b)
{
if (b%2==1)
res = res * ans % mod;
ans = ans * ans % mod;
b/=2;
}
return res;
}
type sum(int l, int r, int ex, int mod)//区间次幂和 2
{
s_it itl = split(l),itr = split(r+1);
type res = 0;
for (; itl != itr; ++itl)
res = (res + (type)(itl->r - itl->l + 1)
*pown(itl->val, type(ex), type(mod))) % mod;
//本质上就是用快速幂把区间相同的数算出来,然后再直接*区间长度
return res;
}
int n, m;
type seed, vmax;
type rd()
{
type ret = seed;
seed = (seed * 7 + 13) % MOD7;
return ret;
}
type a[imax_n];
int main()
{
cin>>n>>m>>seed>>vmax;
for1(i,1,n)
{
a[i] = (rd() % vmax) + 1;
s.insert(node(i,i,a[i]));
}
s.insert(node(n+1, n+1, 0));
int lines = 0;
for1(i,1,m)
{
int op = int(rd() % 4) + 1;
int l = int(rd() % n) + 1;
int r = int(rd() % n) + 1;
if (l > r)
swap(l,r);
int x, y;
if (op == 3)
x = int(rd() % (r-l+1)) + 1;
else
x = int(rd() % vmax) +1;
if (op == 4)
y = int(rd() % vmax) + 1;
if (op == 1)
add(l, r, type(x));
else if (op == 2)
assign(l, r, type(x));
else if (op == 3)
cout<<ranks(l,r,x)<<endl;
else
cout<<sum(l,r,x,y)<<endl;
}
return 0;
}

浙公网安备 33010602011771号